package cluster

import (
	"database/sql"
	"fmt"
	"testing"

	l4g "github.com/alecthomas/log4go"
	"github.com/dailymotion/allure-go"
	"github.com/tidbcloud/qa-PlatformAPIAuto/common"
	"github.com/tidbcloud/qa-PlatformAPIAuto/models"
	sqlpkg "github.com/tidbcloud/qa-PlatformAPIAuto/webScene/pkg/sql"
)

type ServerlessCluster struct {
	*common.DbassRequestInfo

	T *testing.T
}

func (s *ServerlessCluster) Id() string {
	return s.ClusterId
}

func (s *ServerlessCluster) SetId(id string) {
	s.ClusterId = id
}

func (s *ServerlessCluster) Create(provider string) {
	l4g.Info("create tidb cluster")
	if s.ClusterId != "" {
		l4g.Info("tidb cluster already exists")
		return
	}

	s.ClusterId = common.CheckCreateCluster(
		s.T,
		provider,
		true,
		defaultServerlessTidbCount,
		defaultServerlessTikvCount,
		defaultServerlessTiflashCount,
		"", "", "", "",
	)
}

func (s *ServerlessCluster) Execute(dataFunc sqlpkg.Statement) {
	db, err := s.getConnection()
	defer db.Close()
	if err != nil {
		errorMsg := fmt.Errorf("connect to serverless tidb occur error: %s", err)
		l4g.Error(errorMsg)
		allure.FailNow(errorMsg)
	}

	err = dataFunc(db)
	if err != nil {
		errorMsg := fmt.Errorf("init serverless tidb data occur error: %s", err)
		l4g.Error(errorMsg)
		allure.FailNow(errorMsg)
	}
}

func (s *ServerlessCluster) getConnection() (*sql.DB, error) {
	pathParam := map[string]string{
		"org_id":     s.CommonEnv.OrgId,
		"project_id": s.CommonEnv.ProjectId,
		"cluster_id": s.ClusterId,
	}
	callResp := s.DbassRequest(s.T, "getClusterInfo", nil, pathParam, nil, nil)
	httpInfo := common.ParseHttpInfo(callResp)
	if httpInfo.RespStatusCode != common.StatusOK {
		errorMsg := fmt.Errorf("status code is: %d, http details is: %s", httpInfo.RespStatusCode, httpInfo.ToString())
		l4g.Error(errorMsg)
		allure.FailNow(errorMsg)
	}

	clusterResp := &models.CentralGetClusterResp{}
	httpInfo.UnmarshalRespBody(clusterResp)

	tidbAddress := clusterResp.Cluster.Endpoint.Address
	tidbPort := clusterResp.Cluster.Endpoint.Port
	token := *clusterResp.Cluster.Endpoint.Token

	return common.ConnectServerlessUseTLS(*tidbAddress, (int64)(*tidbPort), DefaultPassword, "test", token+".root")
}

func (s *ServerlessCluster) GetDataIngestionProfile() *models.DataflowDataIngestionProfile {
	if s.ClusterId == "" {
		errorMsg := fmt.Errorf("cluster id is empty")
		l4g.Error(errorMsg)
		allure.FailNow(errorMsg)
	}
	pathParam := map[string]string{
		"org_id":     s.CommonEnv.OrgId,
		"project_id": s.CommonEnv.ProjectId,
		"cluster_id": s.ClusterId,
	}

	callResp := s.DbassRequest(s.T, "getDataIngestionProfile", nil, pathParam, nil, nil)
	httpInfo := common.ParseHttpInfo(callResp)
	if httpInfo.RespStatusCode != common.StatusOK {
		errorMsg := fmt.Errorf("status code is: %d, http details is: %s", httpInfo.RespStatusCode, httpInfo.ToString())
		l4g.Error(errorMsg)
		allure.FailNow(errorMsg)
	}
	dataIngestionProfile := &models.DataflowDataIngestionProfile{}
	httpInfo.UnmarshalRespBody(dataIngestionProfile)

	return dataIngestionProfile
}
