package segments

import (
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/sdn/segments"
)

func flattenSegment(d *schema.ResourceData, segmentRecord *segments.SegmentResponse) {
	d.Set("access_group_id", segmentRecord.AccessGroupID)
	d.Set("access_group_name", segmentRecord.AccessGroupName)
	d.Set("created_at", segmentRecord.CreatedAt.String())
	d.Set("description", segmentRecord.Description)
	d.Set("dhcp_v4", flattenDHCPv4(segmentRecord.DHCPv4))
	d.Set("dhcp_v6", flattenDHCPv6(segmentRecord.DHCPv6))
	d.Set("display_name", segmentRecord.DisplayName)
	d.Set("enabled", segmentRecord.Enabled)
	d.Set("l2_connection_port", flattenL2ConnectionPort(segmentRecord.L2ConnectionPort))
	d.Set("logical_ports_info", flattenEntity(segmentRecord.LogicalPortsInfo))
	d.Set("routers_info", flattenEntity(segmentRecord.RoutersInfo))
	d.Set("status", flattenStatus(segmentRecord.Status))
	d.Set("subnet_v4", segmentRecord.SubnetV4)
	d.Set("subnet_v6", segmentRecord.SubnetV6)
	d.Set("type", segmentRecord.Type)
	d.Set("updated_at", segmentRecord.UpdatedAt.String())
	d.Set("version_id", segmentRecord.VersionID)
}

func flattenStatus(s segments.Status) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"operation_status": s.OperationStatus,
		"hypervisors":      flattenHypervisors(s.Hypervisors),
	}
	res = append(res, temp)
	return res
}

func flattenHypervisors(hv []segments.HypervisorStatus) []map[string]interface{} {
	res := make([]map[string]interface{}, 0, len(hv))
	for _, v := range hv {
		temp := map[string]interface{}{
			"operation_status":  v.OperationStatus,
			"name":              v.Name,
			"display_name":      v.DisplayName,
			"hypervisor_status": v.HypervisorStatus,
			"synced_at":         v.SyncedAt.String(),
		}
		res = append(res, temp)
	}
	return res
}

func flattenEntity(ei []segments.EntityInfo) []map[string]interface{} {
	res := make([]map[string]interface{}, 0, len(ei))
	for _, v := range ei {
		temp := map[string]interface{}{
			"display_name": v.DisplayName,
			"id":           v.ID,
		}
		res = append(res, temp)
	}
	return res
}

func flattenDHCPv4(dchp segments.DHCPv4Config) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"dns":                     dchp.DNS,
		"excluded_address_ranges": dchp.ExcludedAddressRanges,
		"gateway":                 dchp.Gateway,
		"id":                      dchp.ID,
		"lease_time":              dchp.LeaseTime,
		"server_ip":               dchp.ServerIP,
		"server_mac":              dchp.ServerMAC,
		"enabled":                 dchp.Enabled,
	}
	res = append(res, temp)
	return res
}

func flattenDHCPv6(dchp segments.DHCPv6Config) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"dns":            dchp.DNS,
		"address_prefix": dchp.AddressPrefix,
		"id":             dchp.ID,
		"lease_time":     dchp.LeaseTime,
		"server_mac":     dchp.ServerMAC,
		"enabled":        dchp.Enabled,
	}
	res = append(res, temp)
	return res
}

func flattenL2ExternalNetwork(net segments.L2ExternalNetwork) []map[string]interface{} {
	return []map[string]interface{}{
		{
			"id":                  net.ID,
			"display_name":        net.DisplayName,
			"description":         net.Description,
			"bridge_network_name": net.BridgeNetworkName,
			"hypervisors":         net.Hypervisors,
			"vlan_tag":            net.VLANTag,
			"version_id":          net.VersionID,
			"created_at":          net.CreatedAt.String(),
			"created_by":          net.CreatedBy,
			"updated_at":          net.UpdatedAt.String(),
			"updated_by":          net.UpdatedBy,
		},
	}
}

func flattenL2ConnectionPort(port *segments.L2ConnectionPort) []map[string]interface{} {
	if port == nil {
		return nil
	}
	return []map[string]interface{}{
		{
			"id":                  port.ID,
			"access_group_id":     port.AccessGroupID,
			"version_id":          port.VersionID,
			"created_at":          port.CreatedAt.String(),
			"created_by":          port.CreatedBy,
			"updated_at":          port.UpdatedAt.String(),
			"updated_by":          port.UpdatedBy,
			"l2_external_network": flattenL2ExternalNetwork(port.L2ExternalNetwork),
		},
	}
}

func flattenSegmentList(sl *segments.ListSegment) []map[string]interface{} {
	res := make([]map[string]interface{}, 0, len(*sl))
	for _, v := range *sl {
		temp := map[string]interface{}{
			"access_group_id":    v.AccessGroupID,
			"access_group_name":  v.AccessGroupName,
			"created_at":         v.CreatedAt.String(),
			"description":        v.Description,
			"dhcp_v4":            flattenDHCPv4(v.DHCPv4),
			"dhcp_v6":            flattenDHCPv6(v.DHCPv6),
			"display_name":       v.DisplayName,
			"enabled":            v.Enabled,
			"l2_connection_port": flattenL2ConnectionPort(v.L2ConnectionPort),
			"logical_ports_info": flattenEntity(v.LogicalPortsInfo),
			"routers_info":       flattenEntity(v.RoutersInfo),
			"status":             flattenStatus(v.Status),
			"id":                 v.ID,
			"subnet_v4":          v.SubnetV4,
			"subnet_v6":          v.SubnetV6,
			"type":               v.Type,
			"updated_at":         v.UpdatedAt.String(),
			"version_id":         v.VersionID,
		}
		res = append(res, temp)
	}
	return res
}
