package common

import (
	"bufio"
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"os"

	l4g "github.com/alecthomas/log4go"

	"github.com/unknwon/goconfig"
)

type Env struct {
	Url                      string
	Authorization            string
	OrgId                    string
	ProjectId                string
	DbPassword               string
	AwsRegion                string
	GcpRegion                string
	TenantVpcId              string
	Subnet                   string
	TenantAccountId          string
	TenantVpcCidr            string
	GcpProjectId             string
	GcpVpcNetworkName        string
	GcpSubnet                string
	BankNumber               string
	AddBankUrl               string
	AwsSourceUrl             string
	AwsParquetS3             string
	AwsAuroraS3              string
	GcpSourceUrl             string
	GcpParquetS3             string
	GcpAuroraS3              string
	importRegion             string
	VisitorEmail             string
	VisitorPassword          string
	Auth0                    string
	ClientId                 string
	RedirectUri              string
	State                    string
	Nonce                    string
	Auth0Client              string
	Refer                    string
	Cicr                     string
	Auth0ClientSecret        string
	Auth0ClientId            string
	Email                    string
	AuditEmail               string
	AdminEmail               string
	AlertEmail               string
	Ec2Host                  string
	CerPath                  string
	KafkaEc2Host             string
	KafkaCerPath             string
	KafkaInstanceId          string
	IamUser                  string
	RouteTableId             string
	LoginUser                string
	GcpVMhost                string
	AwsVpcEc2Host            string
	AwsVpcCerPath            string
	GcpLoginUser             string
	GcpCerPath               string
	GcpInstanceName          string
	TokenPath                string
	AwsRoleArn               string
	AwsCsvS3                 string
	GcpCsvS3                 string
	DevTierRegion            string
	RecievePasswordEmail     string
	ProjectCidr              string
	GcpVpcCidr               string
	AwsSnappyParquetS3       string
	GcpSnappyParquetS3       string
	MysqlUrl                 string
	MysqlUser                string
	MysqlPassword            string
	KafkaUrl                 string
	KafkaTopic               string
	CdcKafkaUrl              string
	AwsCsvObjectNamePattern  string
	AwsCsvTargetTablePattern string

	DMHost        string
	DMPrivateHost string
	DMPort        string
	DMUser        string
	DMPassword    string
	DMType        string

	TidbCpu              string
	TikvCpu              string
	TiflashCpu           string
	VpcIamUser           string
	Port                 string
	AuditLogS3BucketUrl  string
	AuditLogRoleArn      string
	AuditLogGcsBucketUrl string
	AuditLogAwsRegon     string
	KafkaLoginUser       string
	TidbMem              string
	TikvMem              string
	TiflashMem           string
	DBhost               string
	DBport               string
	Password             string
	DBdatabase           string
	DBusername           string

	O11yGlobalUrl    string
	O11yRegionalUrl  string
	GrantType        string
	O11yClientId     string
	ClientSecret     string
	Audience         string
	ThirdProm        string
	DDApiKey         string
	DDApplicationKey string

	LocalImportFileName           string
	LocalImportFilePath           string
	LocalImportFileSize           string
	LocalImportExceptRowCount     string
	LocalImportExceptColumnsCount string

	Chat2queryUser string
	Chat2User      string

	FeishuHost      string
	FeishuAppId     string
	FeishuAppSecret string
	RunUser         string

	ServerlessPlVPCId      string
	ServerlessPlEC2        string
	ServerlessPlCerPath    string
	RequireSecureTransport string

	GcsUri            string
	S3Uri             string
	AccessKey         string
	SecretKey         string
	ObservabilityHost string
}

type UrlInfo struct {
	UrlName   string
	UrlPath   string
	UrlMethod string
	//UrlRespStatus int
	//UrlCheckInfo interface{}
}

type XAccount struct {
	VpcId                   string
	SgId                    string
	SubnetId1               string
	SubnetId2               string
	SubnetId3               string
	BucketName              string
	KmsKeyArn               string
	PcaArnClusterComponents string
	PcaArnClient            string
	RoleArnTidbCloud        string
	RoleArnEks              string
	RoleArnNode             string
	AwsDumplingUrl          string
	Ec2User                 string
	Ec2Host                 string
	Ec2CerPath              string

	Provider     string
	Region       string
	ProjectId    string
	TidbCount    string
	PdCount      string
	TikvCount    string
	TiflashCount string
	TidbCpu      string
	TikvCpu      string
	TiflashCpu   string
}

func GetCommonInfo(environment string) Env {
	var env Env
	config, err := goconfig.LoadConfigFile("../conf/" + environment + "common.conf")
	if err != nil {
		fmt.Println("get config file error")
		os.Exit(-1)
	}
	env.Url, _ = config.GetValue("env", "url")
	env.AddBankUrl, _ = config.GetValue("env", "addBankUrl")
	env.Auth0, _ = config.GetValue("env", "auth0")
	env.Refer, _ = config.GetValue("env", "refer")
	env.Auth0ClientSecret, _ = config.GetValue("env", "auth0ClientSecret")
	env.Auth0ClientId, _ = config.GetValue("env", "auth0ClientId")

	env.Authorization, _ = config.GetValue("header", "authorization")
	env.TokenPath, _ = config.GetValue("header", "tokenPath")
	env.OrgId, _ = config.GetValue("cluster", "orgId")
	env.ProjectId, _ = config.GetValue("cluster", "projectId")
	env.DbPassword, _ = config.GetValue("cluster", "dbPassword")
	env.AwsRegion, _ = config.GetValue("cluster", "awsRegion")
	env.DevTierRegion, _ = config.GetValue("cluster", "devTierRegion")
	env.GcpRegion, _ = config.GetValue("cluster", "gcpRegion")
	env.Email, _ = config.GetValue("cluster", "email")
	env.AlertEmail, _ = config.GetValue("cluster", "alertEmail")
	env.AuditEmail, _ = config.GetValue("cluster", "auditEmail")
	env.AdminEmail, _ = config.GetValue("cluster", "adminEmail")
	env.RecievePasswordEmail, _ = config.GetValue("cluster", "recievePasswordEmail")
	env.ProjectCidr, _ = config.GetValue("cluster", "projectCidr")

	env.TidbCpu, _ = config.GetValue("cluster", "tidbCpu")
	env.TikvCpu, _ = config.GetValue("cluster", "tikvCpu")
	env.TiflashCpu, _ = config.GetValue("cluster", "tiflashCpu")
	env.TidbMem, _ = config.GetValue("cluster", "tidbMem")
	env.TikvMem, _ = config.GetValue("cluster", "tikvMem")
	env.TiflashMem, _ = config.GetValue("cluster", "tiflashMem")
	env.Port, _ = config.GetValue("cluster", "port")

	env.TenantVpcId, _ = config.GetValue("awsvpc", "tenantVpcId")
	env.Subnet, _ = config.GetValue("awsvpc", "subnet")
	env.TenantAccountId, _ = config.GetValue("awsvpc", "tenantAccountId")
	env.TenantVpcCidr, _ = config.GetValue("awsvpc", "tenantVpcCidr")

	env.GcpProjectId, _ = config.GetValue("gcpvpc", "projectId")
	env.GcpVpcCidr, _ = config.GetValue("gcpvpc", "gcpVpcCidr")
	env.GcpVpcNetworkName, _ = config.GetValue("gcpvpc", "vpcNetworkName")
	env.GcpSubnet, _ = config.GetValue("gcpvpc", "subnet")

	env.BankNumber, _ = config.GetValue("bankcard", "number")

	env.AwsSourceUrl, _ = config.GetValue("import", "awsSourceUrl")
	env.importRegion, _ = config.GetValue("import", "region")
	env.AwsParquetS3, _ = config.GetValue("import", "awsParquetS3")
	env.AwsSnappyParquetS3, _ = config.GetValue("import", "awsSnappyParquetS3")
	env.AwsAuroraS3, _ = config.GetValue("import", "awsAuroraS3")
	env.AwsRoleArn, _ = config.GetValue("import", "awsRoleArn")
	env.AwsCsvS3, _ = config.GetValue("import", "awsCsvS3")
	env.GcpCsvS3, _ = config.GetValue("import", "gcpCsvS3")
	env.GcpSourceUrl, _ = config.GetValue("import", "gcpSourceUrl")
	env.GcpParquetS3, _ = config.GetValue("import", "gcpParquetS3")
	env.GcpSnappyParquetS3, _ = config.GetValue("import", "gcpSnappyParquetS3")
	env.GcpAuroraS3, _ = config.GetValue("import", "gcpAuroraS3")
	env.AwsCsvObjectNamePattern, _ = config.GetValue("import", "awsCsvObjectNamePattern")
	env.AwsCsvTargetTablePattern, _ = config.GetValue("import", "awsCsvTargetTablePattern")

	env.VisitorEmail, _ = config.GetValue("accessUser", "visitorEmail")
	env.VisitorPassword, _ = config.GetValue("accessUser", "visitorPassword")
	env.ClientId, _ = config.GetValue("accessUser", "clientId")
	env.RedirectUri, _ = config.GetValue("accessUser", "redirectUri")
	env.State, _ = config.GetValue("accessUser", "state")
	env.Nonce, _ = config.GetValue("accessUser", "nonce")
	env.Auth0Client, _ = config.GetValue("accessUser", "auth0Client")

	env.Cicr, _ = config.GetValue("filter", "cidr")

	env.Ec2Host, _ = config.GetValue("EC2", "ec2Host")
	env.CerPath, _ = config.GetValue("EC2", "cerPath")
	env.IamUser, _ = config.GetValue("EC2", "iamUser")

	env.LoginUser, _ = config.GetValue("EC2", "loginUser")
	env.KafkaEc2Host, _ = config.GetValue("EC2", "kafkaEc2Host")
	env.KafkaCerPath, _ = config.GetValue("EC2", "kafkaCerPath")
	env.KafkaInstanceId, _ = config.GetValue("EC2", "kafkaInstanceId")
	env.AwsVpcEc2Host, _ = config.GetValue("AwsVpcVm", "ec2Host")
	env.AwsVpcCerPath, _ = config.GetValue("AwsVpcVm", "cerPath")
	env.RouteTableId, _ = config.GetValue("AwsVpcVm", "routeTableId")
	env.VpcIamUser, _ = config.GetValue("AwsVpcVm", "iamUser")

	env.GcpLoginUser, _ = config.GetValue("GCPvm", "gcpLoginUser")
	env.GcpCerPath, _ = config.GetValue("GCPvm", "gcpCerPath")
	env.GcpVMhost, _ = config.GetValue("GCPvm", "vmHost")
	env.GcpInstanceName, _ = config.GetValue("GCPvm", "instanceName")

	env.MysqlUrl, _ = config.GetValue("dataToMysql", "mysqlUrl")
	env.MysqlUser, _ = config.GetValue("dataToMysql", "mysqlUser")
	env.MysqlPassword, _ = config.GetValue("dataToMysql", "mysqlPassword")

	env.KafkaUrl, _ = config.GetValue("dataToKafka", "kafkaUrl")
	env.KafkaTopic, _ = config.GetValue("dataToKafka", "kafkaTopic")
	env.KafkaLoginUser, _ = config.GetValue("dataToKafka", "loginUser")

	env.CdcKafkaUrl, _ = config.GetValue("kafka", "url")

	env.AuditLogS3BucketUrl, _ = config.GetValue("auditlog", "AuditLogs3BucketUrl")
	env.AuditLogRoleArn, _ = config.GetValue("auditlog", "AuditLogroleArn")
	env.AuditLogGcsBucketUrl, _ = config.GetValue("auditlog", "AuditLoggcsBucketUrl")
	env.AuditLogAwsRegon, _ = config.GetValue("auditlog", "AuditLogAwsRegon")

	env.DBhost, _ = config.GetValue("DB", "host")
	env.DBport, _ = config.GetValue("DB", "port")
	env.Password, _ = config.GetValue("DB", "password")
	env.DBdatabase, _ = config.GetValue("DB", "database")
	env.DBusername, _ = config.GetValue("DB", "username")

	env.O11yGlobalUrl, _ = config.GetValue("o11y", "globalServer")
	env.O11yRegionalUrl, _ = config.GetValue("o11y", "regionalServer")
	env.GrantType, _ = config.GetValue("o11y", "grant_type")
	env.O11yClientId, _ = config.GetValue("o11y", "client_id")
	env.ClientSecret, _ = config.GetValue("o11y", "client_secret")
	env.Audience, _ = config.GetValue("o11y", "audience")
	env.ThirdProm, _ = config.GetValue("o11y", "thirdProm")
	env.DDApiKey, _ = config.GetValue("datadog", "apiKey")
	env.DDApplicationKey, _ = config.GetValue("datadog", "applicationKey")

	env.DMHost, _ = config.GetValue("DM", "host")
	env.DMPrivateHost, _ = config.GetValue("DM", "privateHost")
	env.DMPort, _ = config.GetValue("DM", "port")
	env.DMUser, _ = config.GetValue("DM", "user")
	env.DMPassword, _ = config.GetValue("DM", "password")
	env.DMType, _ = config.GetValue("DM", "type")

	env.LocalImportFileName, _ = config.GetValue("localImport", "fileName")
	env.LocalImportFilePath, _ = config.GetValue("localImport", "filePath")
	env.LocalImportFileSize, _ = config.GetValue("localImport", "fileSize")
	env.LocalImportExceptRowCount, _ = config.GetValue("localImport", "exceptRowCount")
	env.LocalImportExceptColumnsCount, _ = config.GetValue("localImport", "exceptColumnsCount")

	env.Chat2queryUser, _ = config.GetValue("chat2query", "newUser")
	env.Chat2User, _ = config.GetValue("chat2query", "newUser2")

	env.FeishuHost, _ = config.GetValue("FeiShu", "host")
	env.FeishuAppId, _ = config.GetValue("FeiShu", "app_id")
	env.FeishuAppSecret, _ = config.GetValue("FeiShu", "app_secret")

	env.ServerlessPlVPCId, _ = config.GetValue("Serverless", "plVpcId")
	env.ServerlessPlEC2, _ = config.GetValue("Serverless", "plEC2")
	env.ServerlessPlCerPath, _ = config.GetValue("Serverless", "plCerPath")

	env.GcsUri, _ = config.GetValue("GCS", "gcsUri")
	env.S3Uri, _ = config.GetValue("S3", "s3Uri")

	env.ObservabilityHost, _ = config.GetValue("observability", "host")

	l4g.Info("The common environment setup finished!")

	return env

}

func GetUrlInfo() []UrlInfo {
	var urlInfos []UrlInfo
	csvFile, _ := os.Open("../conf/urlConfig.csv")
	reader := csv.NewReader(bufio.NewReader(csvFile))

	for {
		line, error := reader.Read()
		if error == io.EOF {
			break
		} else if error != nil {
			log.Fatal(error)
		}
		urlInfos = append(urlInfos, UrlInfo{
			UrlName:   line[0],
			UrlPath:   line[1],
			UrlMethod: line[2]})
	}

	return urlInfos
}

func GetxAccountInfo(environment string) XAccount {
	var xAccount XAccount
	config, err := goconfig.LoadConfigFile("../conf/" + environment + "XAccount.conf")
	if err != nil {
		fmt.Println("get config file error")
		os.Exit(-1)
	}
	xAccount.VpcId, _ = config.GetValue("network", "vpcId")
	xAccount.SgId, _ = config.GetValue("network", "sgId")
	xAccount.SubnetId1, _ = config.GetValue("network", "subnetId1")
	xAccount.SubnetId2, _ = config.GetValue("network", "subnetId2")
	xAccount.SubnetId3, _ = config.GetValue("network", "subnetId3")

	xAccount.BucketName, _ = config.GetValue("s3", "bucketName")

	xAccount.KmsKeyArn, _ = config.GetValue("security", "kmsKeyArn")
	xAccount.PcaArnClusterComponents, _ = config.GetValue("security", "pcaArnClusterComponents")
	xAccount.PcaArnClient, _ = config.GetValue("security", "pcaArnClient")

	xAccount.RoleArnTidbCloud, _ = config.GetValue("role", "roleArnTidbCloud")
	xAccount.RoleArnEks, _ = config.GetValue("role", "roleArnEks")
	xAccount.RoleArnNode, _ = config.GetValue("role", "roleArnNode")
	xAccount.AwsDumplingUrl, _ = config.GetValue("import", "awsDumplingUrl")

	xAccount.Ec2User, _ = config.GetValue("ec2", "ec2User")
	xAccount.Ec2Host, _ = config.GetValue("ec2", "ec2Host")
	xAccount.Ec2CerPath, _ = config.GetValue("ec2", "ec2CerPath")

	xAccount.Provider, _ = config.GetValue("cluster", "provider")
	xAccount.Region, _ = config.GetValue("cluster", "region")
	xAccount.ProjectId, _ = config.GetValue("cluster", "projectId")
	xAccount.PdCount, _ = config.GetValue("cluster", "pdCount")
	xAccount.TidbCount, _ = config.GetValue("cluster", "tidbCount")
	xAccount.TikvCount, _ = config.GetValue("cluster", "tikvCount")
	xAccount.TiflashCount, _ = config.GetValue("cluster", "tiflashCount")
	xAccount.TidbCpu, _ = config.GetValue("cluster", "tidbCpu")
	xAccount.TikvCpu, _ = config.GetValue("cluster", "tikvCpu")
	xAccount.TiflashCpu, _ = config.GetValue("cluster", "tiflashCpu")

	return xAccount
}

type MetricQuery struct {
	Desc    string
	Key     string
	query   string
	hasData string
	Value   string
}

func GetMetricQuery(fileName string, isServerless bool) []MetricQuery {
	var Queries []MetricQuery
	filePath := fmt.Sprintf("../conf/%s", fileName)
	csvFile, _ := os.Open(filePath)
	reader := csv.NewReader(bufio.NewReader(csvFile))
	reader.Comma = ';'

	for {
		line, error := reader.Read()
		if error == io.EOF {
			break
		} else if error != nil {
			l4g.Error(error)
			return Queries
		}
		if isServerless {
			Queries = append(Queries, MetricQuery{
				Desc:    line[0],
				Key:     line[1],
				query:   line[2],
				hasData: line[3],
				Value:   line[4]})
		} else {
			Queries = append(Queries, MetricQuery{
				Desc:    "",
				Key:     "",
				query:   line[0],
				hasData: line[1],
				Value:   line[2]})
		}

	}
	l4g.Info("Has load metrics success!")

	return Queries
}
