package main

import (
	"context"
	"os"
	"os/exec"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/yaml"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	pkgconfig "github.com/tidbcloud/infra-provider/pkg/config"
)

type Checker interface {
	Check(ctx context.Context) error
}

type eksChecker struct {
	cmd     string
	cfgPath string

	infraKubeconfig     string
	dataplaneKubeconfig string
	cluster             string
	readonlyRoleName    string
	region              string
	providerType        string
}

func NewChecker(cmd, rootCfg, infraKubeconfig, dataplaneKubeconfig, cluster, readonlyRoleName, providerType, region string) Checker {
	return &eksChecker{
		cmd:                 cmd,
		cfgPath:             rootCfg,
		infraKubeconfig:     infraKubeconfig,
		dataplaneKubeconfig: dataplaneKubeconfig,
		cluster:             cluster,
		readonlyRoleName:    readonlyRoleName,
		region:              region,
		providerType:        providerType,
	}
}

func (c *eksChecker) overrideRootConfig() ([]byte, error) {
	cfg, err := pkgconfig.LoadRootConfig(c.cfgPath)
	if err != nil {
		return nil, err
	}

	cfg.DryRun.Enabled = true
	cfg.ClusterController.DataplaneKubeconfig = c.dataplaneKubeconfig
	cfg.FullManage.AssumeRoleName = c.readonlyRoleName
	// disable clinic activity
	cfg.ClusterController.ConfigChange.Activity.Enabled = false

	cfg.Predicate = metav1.LabelSelector{
		MatchLabels: map[string]string{
			"tags.tidbcloud.com/cluster": c.cluster,
			cloudv1.RegionLabel:          c.region,
			cloudv1.ProviderTypeLabel:    c.providerType,
		},
	}
	cfg.Network.Region = c.region

	data, err := yaml.Marshal(&cfg)
	if err != nil {
		return nil, err
	}

	return data, nil

}

func (c *eksChecker) Check(ctx context.Context) error {
	data, err := c.overrideRootConfig()
	if err != nil {
		return err
	}

	rootCfgFile, err := os.CreateTemp("", "root-config-")
	if err != nil {
		return err
	}
	defer os.Remove(rootCfgFile.Name())

	if _, err := rootCfgFile.Write(data); err != nil {
		return err
	}

	pwd, err := os.Getwd()
	if err != nil {
		return err
	}

	args := []string{
		"--root-config",
		rootCfgFile.Name(),
		"--infra-kubeconfig",
		c.infraKubeconfig,
		"--enable-network-controllers=false",
		"--region",
		c.region,
	}
	cmd := exec.CommandContext(ctx, c.cmd, args...)

	cmd.Dir = pwd
	cmd.Env = os.Environ()
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}
