package flattens

import (
	"context"
	"fmt"

	"github.com/hashicorp/terraform-plugin-framework/diag"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"github.com/hashicorp/terraform-plugin-log/tflog"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/client"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/flattens"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/stack/models"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/stack/utilities"
)

// StackListDataSource flattens data source for Stacks list.
// Return error in case data source is not found on the platform.
// Flatten errors are added to tflog.
func StackListDataSource(ctx context.Context, state *models.DataSourceStackListModel, c *client.Client) diag.Diagnostics {
	tflog.Info(ctx, "Start flattens.StackListDataSource")

	diags := diag.Diagnostics{}

	record, err := utilities.StackListDataSourceCheckPresence(ctx, state, c)
	if err != nil {
		diags.AddError(fmt.Sprintf("Cannot get info about Stacks"), err.Error())
		return diags
	}

	tflog.Info(ctx, "flattens.StackListDataSource: before flatten", map[string]any{"recordStacks": record})

	*state = models.DataSourceStackListModel{
		ByID:     state.ByID,
		Name:     state.Name,
		Type:     state.Type,
		Status:   state.Status,
		SortBy:   state.SortBy,
		Page:     state.Page,
		Size:     state.Size,
		Timeouts: state.Timeouts,

		EntryCount: types.Int64Value(int64(record.EntryCount)),
	}

	items := make([]models.InfoStackListModel, 0, len(record.Data))

	for _, stack := range record.Data {
		item := models.InfoStackListModel{
			StackID:            types.Int64Value(int64(stack.ID)),
			Ckey:               types.StringValue(stack.Ckey),
			Meta:               flattens.FlattenSimpleTypeToList(ctx, types.StringType, stack.Meta),
			APIURL:             types.StringValue(stack.APIURL),
			Apikey:             types.StringValue(stack.Apikey),
			AppID:              types.StringValue(stack.AppID),
			CPUAllocationRatio: types.Float64Value(stack.CPUAllocationRatio),
			Description:        types.StringValue(stack.Description),
			Descr:              types.StringValue(stack.Descr),
			Drivers:            flattens.FlattenSimpleTypeToList(ctx, types.StringType, stack.Drivers),
			Eco:                types.StringValue(flattenEco(stack.Eco)),
			Error:              types.Int64Value(int64(stack.Error)),
			GID:                types.Int64Value(int64(stack.GID)),
			GUID:               types.Int64Value(int64(stack.GUID)),
			Images:             flattens.FlattenSimpleTypeToList(ctx, types.Int64Type, stack.Images),
			Login:              types.StringValue(stack.Login),
			MemAllocationRatio: types.Float64Value(stack.MemAllocationRatio),
			Name:               types.StringValue(stack.Name),
			Password:           types.StringValue(stack.Password),
			ReferenceID:        types.StringValue(stack.ReferenceID),
			Status:             types.StringValue(stack.Status),
			Type:               types.StringValue(stack.Type),
		}

		packages := models.PackagesStackListModel{}
		packages.LibvirtBin = &models.LibvirtBinStackListModel{
			InstalledSize: types.StringValue(stack.Packages.LibvirtBin.InstalledSize),
			Ver:           types.StringValue(stack.Packages.LibvirtBin.Ver),
		}

		packages.LibvirtDaemon = &models.LibvirtDaemonStackListModel{
			InstalledSize: types.StringValue(stack.Packages.LibvirtDaemon.InstalledSize),
			Ver:           types.StringValue(stack.Packages.LibvirtDaemon.Ver),
		}

		packages.Lvm2Lockd = &models.Lvm2LockdStackListModel{
			InstalledSize: types.StringValue(stack.Packages.Lvm2Lockd.InstalledSize),
			Ver:           types.StringValue(stack.Packages.Lvm2Lockd.Ver),
		}

		packages.OpenvswitchCommon = &models.OpenvswitchCommonStackListModel{
			InstalledSize: types.StringValue(stack.Packages.OpenvswitchCommon.InstalledSize),
			Ver:           types.StringValue(stack.Packages.OpenvswitchCommon.Ver),
		}

		packages.OpenvswitchSwitch = &models.OpenvswitchSwitchStackListModel{
			InstalledSize: types.StringValue(stack.Packages.OpenvswitchSwitch.InstalledSize),
			Ver:           types.StringValue(stack.Packages.OpenvswitchSwitch.Ver),
		}

		packages.QemuSystemX86 = &models.QemuSystemX86StackListModel{
			InstalledSize: types.StringValue(stack.Packages.QemuSystemX86.InstalledSize),
			Ver:           types.StringValue(stack.Packages.QemuSystemX86.Ver),
		}

		packages.Sanlock = &models.SanlockStackListModel{
			InstalledSize: types.StringValue(stack.Packages.Sanlock.InstalledSize),
			Ver:           types.StringValue(stack.Packages.Sanlock.Ver),
		}

		item.Packages = &packages

		items = append(items, item)
	}

	state.Items = items

	tflog.Info(ctx, "flattens.StackListDataSource: after flatten")

	tflog.Info(ctx, "End flattens.StackListDataSource")
	return nil
}
