/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.

Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort

Please see README.md to learn where to place source code so that it
builds seamlessly.

Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/

package netobjgroups

import (
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func hypervisorsInfoComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"operation_status":  {Type: schema.TypeString, Computed: true},
				"name":              {Type: schema.TypeString, Computed: true},
				"display_name":      {Type: schema.TypeString, Computed: true},
				"hypervisor_status": {Type: schema.TypeString, Computed: true},
				"synced_at":         {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func statusComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"operation_status":  {Type: schema.TypeString, Computed: true},
				"hypervisor_status": {Type: schema.TypeString, Computed: true},
				"hypervisors":       hypervisorsInfoComputedSchema(),
			},
		},
	}
}

func logicalPortAddressesComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"ip":              {Type: schema.TypeString, Computed: true},
				"ip_type":         {Type: schema.TypeString, Computed: true},
				"is_discovered":   {Type: schema.TypeBool, Computed: true},
				"is_primary":      {Type: schema.TypeBool, Computed: true},
				"mac":             {Type: schema.TypeString, Computed: true},
				"id":              {Type: schema.TypeString, Computed: true},
				"logical_port_id": {Type: schema.TypeString, Computed: true},
				"assigned_at":     {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func bindingsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"id":                     {Type: schema.TypeString, Computed: true},
				"segment_display_name":   {Type: schema.TypeString, Computed: true},
				"segment_id":             {Type: schema.TypeString, Computed: true},
				"port_security":          {Type: schema.TypeBool, Computed: true},
				"address_detection":      {Type: schema.TypeBool, Computed: true},
				"version_id":             {Type: schema.TypeInt, Computed: true},
				"created_at":             {Type: schema.TypeString, Computed: true},
				"updated_at":             {Type: schema.TypeString, Computed: true},
				"logical_port_addresses": logicalPortAddressesComputedSchema(),
			},
		},
	}
}

func excludeFirewallComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"exclusion_reason":                {Type: schema.TypeString, Computed: true},
				"logical_port_addresses_excluded": {Type: schema.TypeBool, Computed: true},
				"logical_port_excluded":           {Type: schema.TypeBool, Computed: true},
			},
		},
	}
}

func labelsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"vm_id":   {Type: schema.TypeString, Computed: true},
				"vm_name": {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func ipv6ConfigComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"address_mode":       {Type: schema.TypeString, Computed: true},
				"enable_periodic_ra": {Type: schema.TypeBool, Computed: true},
				"interval_ra":        {Type: schema.TypeInt, Computed: true},
				"router_preference":  {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func routerGatewayPortComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"created_at":          {Type: schema.TypeString, Computed: true},
				"description":         {Type: schema.TypeString, Computed: true},
				"id":                  {Type: schema.TypeString, Computed: true},
				"router_display_name": {Type: schema.TypeString, Computed: true},
				"router_id":           {Type: schema.TypeString, Computed: true},
				"snat_enabled":        {Type: schema.TypeBool, Computed: true},
				"updated_at":          {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func logicalPortSchemaFields() map[string]*schema.Schema {
	return map[string]*schema.Schema{
		"id":                       {Type: schema.TypeString, Computed: true},
		"access_group_id":          {Type: schema.TypeString, Computed: true},
		"access_group_name":        {Type: schema.TypeString, Computed: true},
		"adapter_mac":              {Type: schema.TypeString, Computed: true},
		"address_detection":        {Type: schema.TypeBool, Computed: true},
		"description":              {Type: schema.TypeString, Computed: true},
		"created_at":               {Type: schema.TypeString, Computed: true},
		"display_name":             {Type: schema.TypeString, Computed: true},
		"enabled":                  {Type: schema.TypeBool, Computed: true},
		"exclude_firewall":         excludeFirewallComputedSchema(),
		"external_network_id":      {Type: schema.TypeString, Computed: true},
		"hypervisor":               {Type: schema.TypeString, Computed: true},
		"hypervisor_display_name":  {Type: schema.TypeString, Computed: true},
		"labels":                   labelsComputedSchema(),
		"live_migration_target_hv": {Type: schema.TypeString, Computed: true},
		"status":                   statusComputedSchema(),
		"bindings":                 bindingsComputedSchema(),
		"unique_identifier":        {Type: schema.TypeString, Computed: true},
		"updated_at":               {Type: schema.TypeString, Computed: true},
		"version_id":               {Type: schema.TypeInt, Computed: true},
	}
}

func logicalPortsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: logicalPortSchemaFields(),
		},
	}
}

func l2ExternalNetworkComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"bridge_network_name": {Type: schema.TypeString, Computed: true},
				"created_at":          {Type: schema.TypeString, Computed: true},
				"description":         {Type: schema.TypeString, Computed: true},
				"display_name":        {Type: schema.TypeString, Computed: true},
				"hypervisors": {
					Type:     schema.TypeList,
					Computed: true,
					Elem:     &schema.Schema{Type: schema.TypeString},
				},
				"id":         {Type: schema.TypeString, Computed: true},
				"updated_at": {Type: schema.TypeString, Computed: true},
				"version_id": {Type: schema.TypeInt, Computed: true},
				"vlan_tag":   {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func l2ConnectionPortsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"id":                  {Type: schema.TypeString, Computed: true},
				"access_group_id":     {Type: schema.TypeString, Computed: true},
				"created_at":          {Type: schema.TypeString, Computed: true},
				"updated_at":          {Type: schema.TypeString, Computed: true},
				"version_id":          {Type: schema.TypeInt, Computed: true},
				"l2_external_network": l2ExternalNetworkComputedSchema(),
			},
		},
	}
}

func appliedNetObjectGroupsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"id":         {Type: schema.TypeString, Computed: true},
				"name":       {Type: schema.TypeString, Computed: true},
				"version_id": {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func securityRuleNetObjectComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"display_name":        {Type: schema.TypeString, Computed: true},
				"net_address_pool_id": {Type: schema.TypeString, Computed: true},
				"net_object_group_id": {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func securityRuleFiltersComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"all":                  {Type: schema.TypeBool, Computed: true},
				"arp":                  {Type: schema.TypeBool, Computed: true},
				"dhcp":                 {Type: schema.TypeBool, Computed: true},
				"expression":           {Type: schema.TypeString, Computed: true},
				"icmp":                 {Type: schema.TypeBool, Computed: true},
				"ip":                   {Type: schema.TypeBool, Computed: true},
				"ip_v4":                {Type: schema.TypeBool, Computed: true},
				"ip_v6":                {Type: schema.TypeBool, Computed: true},
				"keep_opened_sessions": {Type: schema.TypeBool, Computed: true},
				"nd":                   {Type: schema.TypeBool, Computed: true},
				"tcp":                  {Type: schema.TypeBool, Computed: true},
				"tcp_dst_ports": {
					Type:     schema.TypeList,
					Computed: true,
					Elem:     &schema.Schema{Type: schema.TypeString},
				},
				"udp": {Type: schema.TypeBool, Computed: true},
				"udp_dst_ports": {
					Type:     schema.TypeList,
					Computed: true,
					Elem:     &schema.Schema{Type: schema.TypeString},
				},
			},
		},
	}
}

func securityRuleFilterComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"name":    {Type: schema.TypeString, Computed: true},
				"filters": securityRuleFiltersComputedSchema(),
			},
		},
	}
}

func securityRulesComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"access_group_id":        {Type: schema.TypeString, Computed: true},
				"action":                 {Type: schema.TypeString, Computed: true},
				"description":            {Type: schema.TypeString, Computed: true},
				"destination_net_object": securityRuleNetObjectComputedSchema(),
				"direction":              {Type: schema.TypeString, Computed: true},
				"display_name":           {Type: schema.TypeString, Computed: true},
				"enabled":                {Type: schema.TypeBool, Computed: true},
				"filter":                 securityRuleFilterComputedSchema(),
				"id":                     {Type: schema.TypeString, Computed: true},
				"log_enabled":            {Type: schema.TypeBool, Computed: true},
				"log_name":               {Type: schema.TypeString, Computed: true},
				"log_severity":           {Type: schema.TypeString, Computed: true},
				"priority":               {Type: schema.TypeInt, Computed: true},
				"security_policy_id":     {Type: schema.TypeString, Computed: true},
				"source_net_object":      securityRuleNetObjectComputedSchema(),
				"statistics_enabled":     {Type: schema.TypeBool, Computed: true},
				"type":                   {Type: schema.TypeString, Computed: true},
				"version_id":             {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func securityPoliciesComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"access_group_id":           {Type: schema.TypeString, Computed: true},
				"access_group_name":         {Type: schema.TypeString, Computed: true},
				"applied_net_object_groups": appliedNetObjectGroupsComputedSchema(),
				"created_at":                {Type: schema.TypeString, Computed: true},
				"description":               {Type: schema.TypeString, Computed: true},
				"display_name":              {Type: schema.TypeString, Computed: true},
				"enabled":                   {Type: schema.TypeBool, Computed: true},
				"end_priority":              {Type: schema.TypeInt, Computed: true},
				"id":                        {Type: schema.TypeString, Computed: true},
				"security_rules":            securityRulesComputedSchema(),
				"start_priority":            {Type: schema.TypeInt, Computed: true},
				"status":                    statusComputedSchema(),
				"type":                      {Type: schema.TypeString, Computed: true},
				"version_id":                {Type: schema.TypeInt, Computed: true},
				"updated_at":                {Type: schema.TypeString, Computed: true},
			},
		},
	}
}

func gateawayPortsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"created_at":           {Type: schema.TypeString, Computed: true},
				"description":          {Type: schema.TypeString, Computed: true},
				"external_l4_port_max": {Type: schema.TypeInt, Computed: true},
				"external_l4_port_min": {Type: schema.TypeInt, Computed: true},
				"id":                   {Type: schema.TypeString, Computed: true},
				"snat_enabled":         {Type: schema.TypeBool, Computed: true},
				"status":               statusComputedSchema(),
				"updated_at":           {Type: schema.TypeString, Computed: true},
				"version_id":           {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func policiesComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"action":       {Type: schema.TypeString, Computed: true},
				"created_at":   {Type: schema.TypeString, Computed: true},
				"display_name": {Type: schema.TypeString, Computed: true},
				"enabled":      {Type: schema.TypeBool, Computed: true},
				"id":           {Type: schema.TypeString, Computed: true},
				"match":        {Type: schema.TypeString, Computed: true},
				"next_ipv4_address": {
					Type:     schema.TypeList,
					Computed: true,
					Elem:     &schema.Schema{Type: schema.TypeString},
				},
				"next_ipv6_address": {
					Type:     schema.TypeList,
					Computed: true,
					Elem:     &schema.Schema{Type: schema.TypeString},
				},
				"priority":   {Type: schema.TypeInt, Computed: true},
				"updated_at": {Type: schema.TypeString, Computed: true},
				"version_id": {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func segmentComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"access_group_id":   {Type: schema.TypeString, Computed: true},
				"access_group_name": {Type: schema.TypeString, Computed: true},
				"created_at":        {Type: schema.TypeString, Computed: true},
				"description":       {Type: schema.TypeString, Computed: true},
				"display_name":      {Type: schema.TypeString, Computed: true},
				"enabled":           {Type: schema.TypeBool, Computed: true},
				"id":                {Type: schema.TypeString, Computed: true},
				"subnet_v4":         {Type: schema.TypeString, Computed: true},
				"subnet_v6":         {Type: schema.TypeString, Computed: true},
				"updated_at":        {Type: schema.TypeString, Computed: true},
				"version_id":        {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func routerPortsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"created_at":   {Type: schema.TypeString, Computed: true},
				"description":  {Type: schema.TypeString, Computed: true},
				"enabled":      {Type: schema.TypeBool, Computed: true},
				"id":           {Type: schema.TypeString, Computed: true},
				"ipv4_address": {Type: schema.TypeString, Computed: true},
				"ipv6_address": {Type: schema.TypeString, Computed: true},
				"ipv6_config":  ipv6ConfigComputedSchema(),
				"mac":          {Type: schema.TypeString, Computed: true},
				"segment_id":   {Type: schema.TypeString, Computed: true},
				"segment":      segmentComputedSchema(),
				"status":       statusComputedSchema(),
				"updated_at":   {Type: schema.TypeString, Computed: true},
				"version_id":   {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func routerComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"access_group_id":   {Type: schema.TypeString, Computed: true},
				"access_group_name": {Type: schema.TypeString, Computed: true},
				"created_at":        {Type: schema.TypeString, Computed: true},
				"description":       {Type: schema.TypeString, Computed: true},
				"display_name":      {Type: schema.TypeString, Computed: true},
				"enabled":           {Type: schema.TypeBool, Computed: true},
				"gateaway_ports":    gateawayPortsComputedSchema(),
				"id":                {Type: schema.TypeString, Computed: true},
				"policies":          policiesComputedSchema(),
				"ports":             routerPortsComputedSchema(),
				"status":            statusComputedSchema(),
				"updated_at":        {Type: schema.TypeString, Computed: true},
				"version_id":        {Type: schema.TypeInt, Computed: true},
			},
		},
	}
}

func floatingIPComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"access_group_id":   {Type: schema.TypeString, Computed: true},
				"access_group_name": {Type: schema.TypeString, Computed: true},
				"created_at":        {Type: schema.TypeString, Computed: true},
				"updated_at":        {Type: schema.TypeString, Computed: true},
				"version_id":        {Type: schema.TypeInt, Computed: true},
				"logical_port": {
					Type:     schema.TypeList,
					Computed: true,
					Elem: &schema.Resource{
						Schema: logicalPortSchemaFields(),
					},
				},
				"router": routerComputedSchema(),
			},
		},
	}
}

func externalNetworkPortFieldsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"access_group_id":      {Type: schema.TypeString, Computed: true},
				"access_group_name":    {Type: schema.TypeString, Computed: true},
				"comment":              {Type: schema.TypeString, Computed: true},
				"display_name":         {Type: schema.TypeString, Computed: true},
				"enabled":              {Type: schema.TypeBool, Computed: true},
				"ipv4":                 {Type: schema.TypeString, Computed: true},
				"ipv6":                 {Type: schema.TypeString, Computed: true},
				"ipv6_config":          ipv6ConfigComputedSchema(),
				"mac":                  {Type: schema.TypeString, Computed: true},
				"router_gateaway_port": routerGatewayPortComputedSchema(),
				"floating_ip":          floatingIPComputedSchema(),
			},
		},
	}
}

func externalNetworkPortsComputedSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"id":                     {Type: schema.TypeString, Computed: true},
				"access_group_id":        {Type: schema.TypeString, Computed: true},
				"access_group_name":      {Type: schema.TypeString, Computed: true},
				"bridge_network_name":    {Type: schema.TypeString, Computed: true},
				"comment":                {Type: schema.TypeString, Computed: true},
				"default_gateway_ipv4":   {Type: schema.TypeString, Computed: true},
				"default_gateway_ipv6":   {Type: schema.TypeString, Computed: true},
				"description":            {Type: schema.TypeString, Computed: true},
				"enabled":                {Type: schema.TypeBool, Computed: true},
				"external_network_ports": externalNetworkPortFieldsComputedSchema(),
				"hypervisors": {
					Type:     schema.TypeList,
					Computed: true,
					Elem:     &schema.Schema{Type: schema.TypeString},
				},
				"ipv4":       {Type: schema.TypeString, Computed: true},
				"status":     statusComputedSchema(),
				"version_id": {Type: schema.TypeInt, Computed: true},
				"subnet_v4":  {Type: schema.TypeString, Computed: true},
				"subnet_v6":  {Type: schema.TypeString, Computed: true},
				"created_at": {Type: schema.TypeString, Computed: true},
				"updated_at": {Type: schema.TypeString, Computed: true},
				"vlan_tag":   {Type: schema.TypeInt, Computed: true},
				"mac":        {Type: schema.TypeString, Computed: true},
			},
		},
	}
}
