package env

import (
	"context"
	"fmt"

	ec2v1beta1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1beta1"

	"github.com/tidbcloud/eks-provider/tests/e2e/dag"
	"github.com/tidbcloud/eks-provider/tests/e2e/data"
	"github.com/tidbcloud/eks-provider/tests/e2e/label"
	"github.com/tidbcloud/eks-provider/tests/e2e/suite"
	"github.com/tidbcloud/eks-provider/tests/e2e/utils/helper"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

func init() {
	suite.AddEnv(
		label.New(
			NewUpgradedCluster(
				CloudAWS,
			),
			"upgrade infra provider version from old to new",
			label.CloudAWS,
		),
	)
}

type UpgradedClusterEnv struct {
	Config *Config
	// Reconciler from new infra provider
	Reconciler string `inject:".*InfraProvider"`

	Network            *cloudv1.Network
	Cluster            *cloudv1.Cluster
	EndUserVPC         *ec2v1beta1.VPC
	AWSEndUserLambdaFn string

	cloud string
}

func NewUpgradedCluster(cloud string) dag.Env {
	return &UpgradedClusterEnv{cloud: cloud}
}

func (e *UpgradedClusterEnv) Name() string {
	return WithCloud("UpgradedCluster", e.cloud)
}

func (e *UpgradedClusterEnv) Envs() []string {
	return []string{
		WithCloudAndVersion("InfraProvider", e.cloud, InfraProviderVersionNew),
		WithCloudAndVersion("Cluster", e.cloud, InfraProviderVersionOld),
	}
}

func (e *UpgradedClusterEnv) Setup(ctx context.Context) error {
	if err := helper.TryToUpdate(ctx, e.Config.InfraAPIClient, e.Network, data.WithReconciler(e.Reconciler)); err != nil {
		return fmt.Errorf("cannot update reconciler of network: %w", err)
	}
	if err := helper.TryToUpdate(ctx, e.Config.InfraAPIClient, e.Cluster, data.WithReconciler(e.Reconciler)); err != nil {
		return fmt.Errorf("cannot update reconciler of cluster: %w", err)
	}
	if err := helper.TryToUpdateStatus(ctx, e.Config.InfraAPIClient, e.Network, data.ResetNetworkStatus()); err != nil {
		return fmt.Errorf("cannot reset network status: %w", err)
	}

	if err := helper.TryToUpdateStatus(ctx, e.Config.InfraAPIClient, e.Cluster, data.ResetClusterStatus()); err != nil {
		return fmt.Errorf("cannot reset cluster status: %w", err)
	}

	return nil
}
