package grid

import (
	"encoding/json"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/grid"
	"repository.basistech.ru/BASIS/terraform-provider-decort/internal/flattens"
)

func flattenGrid(d *schema.ResourceData, grid *grid.RecordGrid) {
	d.Set("ckey", grid.CKey)
	d.Set("meta", flattens.FlattenMeta(grid.Meta))
	d.Set("auth_broker", flattens.FlattenMeta(grid.AuthBroker))
	d.Set("name", grid.Name)
	d.Set("flag", grid.Flag)
	d.Set("gid", grid.GID)
	d.Set("guid", grid.GUID)
	d.Set("location_code", grid.LocationCode)
	d.Set("id", grid.ID)
	d.Set("network_modes", grid.NetworkModes)
	d.Set("sdn_support", grid.SDNSupport)

}

func flattenGridList(gl *grid.ListGrids) []map[string]interface{} {
	res := make([]map[string]interface{}, 0, len(gl.Data))
	for _, item := range gl.Data {
		temp := map[string]interface{}{
			"resources":           flattenGridResources(item.Resources),
			"name":                item.Name,
			"auth_broker":         flattens.FlattenMeta(item.AuthBroker),
			"flag":                item.Flag,
			"gid":                 item.GID,
			"guid":                item.GUID,
			"location_code":       item.LocationCode,
			"id":                  item.ID,
			"network_modes":       item.NetworkModes,
			"sdn_support":         item.SDNSupport,
			"zero_access_enabled": item.ZeroAccessEnabled,
		}
		res = append(res, temp)
	}
	return res
}

func flattenGridListConsumption(gl *grid.ListResourceConsumption) []map[string]interface{} {
	res := make([]map[string]interface{}, 0, len(gl.Data))
	for _, item := range gl.Data {
		temp := map[string]interface{}{
			"consumed": flattenGridRecordResource(item.Consumed),
			"reserved": flattenGridRecordResource(item.Reserved),
			"id":       item.GID,
		}
		res = append(res, temp)
	}
	return res
}

func flattenGridResources(r grid.Resources) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"current":  flattenGridRecordResource(r.Current),
		"reserved": flattenGridRecordResource(r.Reserved),
	}
	res = append(res, temp)
	return res
}

func flattenGridRecordResource(rr grid.RecordResource) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"cpu":           rr.CPU,
		"disk_size":     rr.DiskSize,
		"disk_size_max": rr.DiskSizeMax,
		"ext_ips":       rr.ExtIPs,
		"gpu":           rr.GPU,
		"ram":           rr.RAM,
		"seps":          flattenGridSeps(rr.SEPs),
	}
	res = append(res, temp)
	return res
}

func flattenGridSeps(seps map[string]map[string]grid.DiskUsage) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	for sepKey, sepVal := range seps {
		for dataKey, dataVal := range sepVal {
			temp := map[string]interface{}{
				"sep_id":        sepKey,
				"data_name":     dataKey,
				"disk_size":     dataVal.DiskSize,
				"disk_size_max": dataVal.DiskSizeMax,
			}
			res = append(res, temp)
		}
	}
	return res
}

func flattenGridSettings(d *schema.ResourceData, gridSettings *grid.RecordSettingsGrid) {
	limits, _ := json.Marshal(gridSettings.Limits)
	d.Set("allowed_ports", gridSettings.Allowedports)
	d.Set("cleanup_retention_period", gridSettings.CleanupRetentionPeriod)
	d.Set("docker_registry", flattenDockerRegistry(gridSettings.DockerRegistry))
	d.Set("enable_uptime_monitor", gridSettings.EnableUptimeMonitor)
	d.Set("extnet_max_pre_reservations_num", gridSettings.ExtnetMaxPreReservationsNum)
	d.Set("healthcheck_notifications", flattenHealthcheckNotifications(gridSettings.HealthcheckNotifications))
	d.Set("k8s_cleanup_enabled", gridSettings.K8sCleanupEnabled)
	d.Set("limits", string(limits))
	d.Set("location_url", gridSettings.LocationURL)
	d.Set("net_qos", flattenNetQOS(gridSettings.NetQOS))
	d.Set("networks", gridSettings.Networks)
	d.Set("prometheus", flattenPrometheus(gridSettings.Prometheus))
	d.Set("vins_max_pre_reservations_num", gridSettings.VinsMaxPreReservationsNum)
	d.Set("vnfdev_mgmt_net_range", gridSettings.VnfdevMgmtNetRange)
}

func flattenDockerRegistry(dr grid.DockerRegistry) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"password": dr.Password,
		"server":   dr.Server,
		"username": dr.Username,
	}
	res = append(res, temp)
	return res
}

func flattenHealthcheckNotifications(hn grid.HealthcheckNotifications) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"emails": flattenEmails(hn.Emails),
	}
	res = append(res, temp)
	return res
}

func flattenEmails(emails []grid.Emails) []map[string]interface{} {
	res := make([]map[string]interface{}, 0, len(emails))
	for _, email := range emails {
		temp := map[string]interface{}{
			"address": email.Address,
			"enabled": email.Enabled,
		}
		res = append(res, temp)
	}
	return res
}

func flattenNetQOS(netQOS grid.NetQOS) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"extnet": flattenSettingsNetQOS(netQOS.ExtNet),
		"vins":   flattenSettingsNetQOS(netQOS.VINS),
	}
	res = append(res, temp)
	return res
}

func flattenSettingsNetQOS(qos grid.SettingsNetQOS) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"e_rate":   qos.ERate,
		"in_burst": qos.InBurst,
		"in_rate":  qos.InRate,
	}
	res = append(res, temp)
	return res
}

func flattenPrometheus(pr grid.Prometheus) []map[string]interface{} {
	res := make([]map[string]interface{}, 0)
	temp := map[string]interface{}{
		"scrape_interval": pr.ScrapeInterval,
	}
	res = append(res, temp)
	return res
}
