package secgroup

import (
	"context"
	"strconv"

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

func utilitySecurityGroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*secgroup.RecordSecurityGroup, error) {
	c := m.(*controller.ControllerCfg)
	req := secgroup.GetRequest{}
	if d.Id() != "" {
		securityGroupID, _ := strconv.ParseUint(d.Id(), 10, 64)
		req.SecurityGroupID = securityGroupID
	} else {
		req.SecurityGroupID = uint64(d.Get("security_group_id").(int))
	}

	log.Debugf("utilitySecurityGroupCheckPresence: load security group")
	securityGroup, err := c.CloudBroker().SecurityGroup().Get(ctx, req)
	if err != nil {
		return nil, err
	}

	return securityGroup, nil
}

func utilitySecurityGroupHandleHasChanges(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error {
	req := secgroup.UpdateRequest{
		SecurityGroupID: securityGroupID,
	}

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

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

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

	return nil
}

func utilitySecurityGroupUpdateRules(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg, securityGroupID uint64) error {
	oldSet, newSet := d.GetChange("rules")
	deletedRules := (oldSet.(*schema.Set).Difference(newSet.(*schema.Set))).List()
	for _, deletedInterface := range deletedRules {
		deletedItem := deletedInterface.(map[string]interface{})
		ruleID := uint64(deletedItem["id"].(int))
		req := secgroup.DeleteRuleRequest{
			SecurityGroupID: securityGroupID,
			RuleID:          ruleID,
		}
		if _, err := c.CloudBroker().SecurityGroup().DeleteRule(ctx, req); err != nil {
			return err
		}

	}

	addedRules := (newSet.(*schema.Set).Difference(oldSet.(*schema.Set))).List()
	for _, addedInterface := range addedRules {
		addedItem := addedInterface.(map[string]interface{})
		direction := addedItem["direction"].(string)
		ethertype := addedItem["ethertype"].(string)
		protocol := addedItem["protocol"].(string)
		portRangeMin := uint64(addedItem["port_range_min"].(int))
		portRangeMax := uint64(addedItem["port_range_max"].(int))
		remoteIPPrefix := addedItem["remote_ip_prefix"].(string)
		req := secgroup.CreateRuleRequest{
			SecurityGroupID: securityGroupID,
			Direction:       direction,
			Ethertype:       ethertype,
			Protocol:        protocol,
			PortRangeMin:    portRangeMin,
			PortRangeMax:    portRangeMax,
			RemoteIPPrefix:  remoteIPPrefix,
		}

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

	return nil
}
