package stpolicy

import (
	"context"
	"strconv"

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

func utilityStoragePolicyCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stpolicy.InfoStoragePolicy, error) {
	c := m.(*controller.ControllerCfg)
	req := stpolicy.GetRequest{}

	if d.Id() != "" {
		storagePolicyID, _ := strconv.ParseUint(d.Id(), 10, 64)
		req.StoragePolicyID = storagePolicyID
	} else {
		req.StoragePolicyID = uint64(d.Get("storage_policy_id").(int))
	}

	storagePolicyData, err := c.CloudBroker().StPolicy().Get(ctx, req)
	if err != nil {
		return nil, err
	}

	return storagePolicyData, nil
}

func handleStoragePolicyEnabling(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, storagePolicyID uint64, enable bool) error {
	if enable {
		req := stpolicy.EnableRequest{
			StoragePolicyID: storagePolicyID,
		}

		_, err := c.CloudBroker().StPolicy().Enable(ctx, req)
		if err != nil {
			return err
		}
	} else {
		req := stpolicy.DisableRequest{
			StoragePolicyID: storagePolicyID,
		}

		_, err := c.CloudBroker().StPolicy().Disable(ctx, req)
		if err != nil {
			return err
		}
	}

	return nil
}

func utilityStoragePolicyHandleHasChanges(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, storagePolicyID uint64) error {
	req := stpolicy.UpdateRequest{
		StoragePolicyID: storagePolicyID,
	}

	if d.HasChange("name") {
		name := d.Get("name").(string)
		req.Name = name
	}

	if d.HasChange("limit_iops") {
		limitIOPS := uint64(d.Get("limit_iops").(int))
		req.LimitIOPS = limitIOPS
	}

	if d.HasChange("description") {
		description := d.Get("description").(string)
		req.Description = description
	}

	if _, err := c.CloudBroker().StPolicy().Update(ctx, req); err != nil {
		return err
	}

	return nil
}

func utilityStoragePolicyUpdateAccessSEPsPools(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, storagePolicyID uint64) error {
	oldSet, newSet := d.GetChange("access_seps_pools")
	deletedASP := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List()
	for _, deletedInterface := range deletedASP {
		deletedItem := deletedInterface.(map[string]interface{})
		SEPID := uint64(deletedItem["sep_id"].(int))
		poolName := deletedItem["pool_name"].(string)
		req := stpolicy.DeletePoolRequest{
			StoragePolicyID: storagePolicyID,
			SEPID:           SEPID,
			PoolName:        poolName,
		}
		if _, err := c.CloudBroker().StPolicy().DeletePool(ctx, req); err != nil {
			return err
		}
	}

	addedASP := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List()
	for _, addedInterface := range addedASP {
		addedItem := addedInterface.(map[string]interface{})
		SEPID := uint64(addedItem["sep_id"].(int))
		poolName := addedItem["pool_name"].(string)
		req := stpolicy.AddPoolRequest{
			StoragePolicyID: storagePolicyID,
			SEPID:           SEPID,
			PoolName:        poolName,
		}
		if _, err := c.CloudBroker().StPolicy().AddPool(ctx, req); err != nil {
			return err
		}
	}

	return nil
}
