//go:build e2e
// +build e2e

package cases

import (
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/pingcap/log"
	"github.com/tidbcloud/observability/pkg/common/message"
	"k8s.io/apimachinery/pkg/util/rand"

	"github.com/tidbcloud/observability/test/ft/utils"
)

var createdID string
var toDeleteID string
var createdNextGenID string
var createdNextGenAppID string
var toDeleteNextGenID string
var toModifySpecID string
var toPauseResumeID string

const nextgenTenantID = "ft-test-nextgen"

func prepareResource() {
	fmt.Println("prepareResource start")
	defer fmt.Println("prepareResource end")
	cluster := utils.CreateCluster(utils.DefaultCreateSharedReq("111", "222", "333"))
	createdID = cluster.ID
	createdNextGen := utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = nextgenTenantID
		req.BizType = utils.NexgenBizType
		req.ProjectID = ""
		req.AgentNextGen = true
		req.AgentAccessAccount = "552185537300"
		return req
	}))
	createdNextGenID = createdNextGen.ID
	createdNextGenAppID = createdNextGen.ApplicationID
	toDelete := utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = "todelete"
		req.ProjectID = "todelete"
		req.ApplicationID = "todelete"
		return req
	}))
	toDeleteID = toDelete.ID

	toDeleteNextGen := utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = nextgenTenantID
		req.BizType = utils.NexgenBizType
		req.ProjectID = ""
		req.ApplicationID = "todelete"
		req.AgentNextGen = true
		req.AgentAccessAccount = "552185537300"
		return req
	}))
	toDeleteNextGenID = toDeleteNextGen.ID

	toPauseResume := utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = "topauseresume"
		req.ProjectID = "topauseresume"
		req.ApplicationID = "topauseresume"
		return req
	}))
	toPauseResumeID = toPauseResume.ID

	toModifySpec := utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = "tomodifyspec"
		req.ProjectID = "tomodifyspec"
		req.ApplicationID = "tomodifyspec"
		return req
	}))
	toModifySpecID = toModifySpec.ID

	utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = "query1"
		req.ProjectID = "query1"
		req.ApplicationID = "query1"
		return req
	}))
	utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = "query1"
		req.ProjectID = "query1"
		req.ApplicationID = "query2"
		return req
	}))
	utils.CreateCluster(utils.HandleWithDefault(func(req message.CreateClusterReq) message.CreateClusterReq {
		req.TenantID = "query1"
		req.ProjectID = "query3"
		req.ApplicationID = "query3"
		return req
	}))

	time.Sleep(20 * time.Second)
}

func clearResource() {
	utils.ClearFtNamespaces()
}

func TestMain(m *testing.M) {
	//init base info
	fmt.Println("TestMain: Starting initialization")
	os.Environ()

	fmt.Println("TestMain: Loading config")
	utils.PreparConfig("./e2e_config.yaml")

	fmt.Println("TestMain: Preparing token")
	utils.PrepareToken()

	fmt.Println("TestMain: Preparing DS token")
	utils.PrepareDSToken()

	fmt.Println("TestMain: Preparing kube client")
	utils.PrepareKubeClient()

	if utils.GetConfig().RDSConfig != nil {
		log.Info("TestMain: Prepare RDS Client")
		utils.PrepareRDS()
	}

	fmt.Println("TestMain: Setting random ID")
	utils.SetRandomID(rand.String(6))

	// make sure all resource has been cleared before test
	fmt.Println("TestMain: Clearing resources")
	clearResource()

	//prepare some cluster before test
	if !utils.GetService().SkipPrepare {
		fmt.Println("TestMain: Preparing resources")
		prepareResource()
	} else {
		fmt.Println("TestMain: Skipping resource preparation")
	}

	fmt.Println("TestMain: Running tests")
	code := m.Run()

	// clear cluster after test
	fmt.Println("clearResource start")
	time.Sleep(10 * time.Second)
	clearResource()
	fmt.Println("clearResource end")

	os.Exit(code)
}
