package tiup_upgrade

import (
	"context"
	"fmt"
	"net/url"
	"strings"
	"time"

	"github.com/pingcap/endless/pkg/matcher"
	"github.com/pingcap/endless/pkg/workloadnode"
	. "github.com/pingcap/endless/pkg/workloadnode/tiup"
	"github.com/pingcap/log"

	_ "github.com/go-sql-driver/mysql"
	. "github.com/onsi/gomega"
	"github.com/pingcap/test-infra/sdk/core"
	"github.com/pingcap/test-infra/sdk/resource"
	_ "github.com/pingcap/test-infra/sdk/resource/impl/k8s" // register k8s impl

	_ "github.com/pingcap/endless/pkg/client/tidb"
	"go.uber.org/zap"
)

func DASHBOARD_GRAFANA(
	ctx core.TestContext,
	workloadNode resource.WorkloadNode,
	preGrafana string,
	flag string,
) {
	dashboardUrl, _, _, err := workloadNode.Exec(resource.WorkloadNodeExecOptions{Command: "tiup cluster display debug | awk '$1 ~ /Dashboard/ {print $3}'"}) // 直接用
	if err != nil {
		log.Fatal("err info:", zap.String("cmd exec fail:", err.Error()))
	}
	Expect(dashboardUrl).Should(ContainSubstring("dashboard"))
	log.Info("dashboard ", zap.String("dsn:", dashboardUrl))

	grafana, _, _, err := workloadNode.Exec(resource.WorkloadNodeExecOptions{Command: "tiup cluster display debug | awk '$2 ~ /grafana/ {print $1}'"}) // 直接用
	if err != nil {
		log.Fatal("err info:", zap.String("cmd exec fail:", err.Error()))
	}
	log.Info("grafana ", zap.String("dsn:", grafana))

	alert, _, _, err := workloadNode.Exec(resource.WorkloadNodeExecOptions{Command: "tiup cluster display debug | awk '$2 ~ /alert/ {print $1}'"}) // 直接用
	if err != nil {
		log.Fatal("err info:", zap.String("cmd exec fail:", err.Error()))
	}
	log.Info("alert ", zap.String("dsn:", alert))

	robot := ctx.Resource("wkload").(resource.WorkloadNode)
	robotCmd := fmt.Sprintf("sed -i '3d' /upgrade-test/keywords/variables.robot")
	duration := 10 * time.Hour
	ctx2, cancel := context.WithTimeout(ctx, duration)
	defer cancel()
	cmd1 := workloadnode.CommandContext(ctx2, robotCmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	robotCmd = fmt.Sprintf("sed -i '3i${Dashboard_URL}    %s' /upgrade-test/keywords/variables.robot", dashboardUrl)
	cmd1 = workloadnode.CommandContext(ctx2, robotCmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	robotCmd = fmt.Sprintf("sed -i 's/172.16.5.101:13000/%s/g' /upgrade-test/keywords/variables.robot", grafana)
	cmd1 = workloadnode.CommandContext(ctx2, robotCmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	robotCmd = fmt.Sprintf("sed -i 's/172.16.5.101:19093/%s/g' /upgrade-test/keywords/variables.robot", alert)
	cmd1 = workloadnode.CommandContext(ctx2, robotCmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	if preGrafana != "7" {
		if flag == "precheck" {
			robotCmd = fmt.Sprintf("sed -i 's/grafana_7_loc/grafana_loc/g' /upgrade-test/keywords/variables.robot")
		} else {
			robotCmd = fmt.Sprintf("sed -i 's/grafana_loc/grafana_7_loc/g' /upgrade-test/keywords/variables.robot")
		}
		cmd1 = workloadnode.CommandContext(ctx2, robotCmd)
		defer cmd1.Stop()
		Expect(cmd1.Run(robot)).Should(BeNil())
	}

	if flag == "precheck" {
		robotCmd = fmt.Sprintf("robot -i precheck -d /root/wkload/precheck/ /upgrade-test/UI_testcase/tidb_dashboard.robot > /root/wkload/precheck/ui_pre_result.txt")
	} else {
		robotCmd = fmt.Sprintf("robot -i postcheck -d /root/wkload/postcheck/ /upgrade-test/UI_testcase/tidb_dashboard.robot > /root/wkload/postcheck/ui_post_result.txt")
	}
	cmd1 = workloadnode.CommandContext(ctx2, robotCmd)
	defer cmd1.Stop()
	e := cmd1.Run(robot)
	if e != nil {
		log.Info("dashboard ", zap.String("result", e.Error()))
	}

	if flag == "precheck" {
		robotCmd = fmt.Sprintf("robot -i precheck -d /root/wkload/precheck/ /upgrade-test/UI_testcase/grafana.robot >> /root/wkload/precheck/ui_pre_result.txt")
	} else {
		robotCmd = fmt.Sprintf("robot -i postcheck -d /root/wkload/postcheck/ /upgrade-test/UI_testcase/grafana.robot >> /root/wkload/postcheck/ui_post_result.txt")
	}
	cmd1 = workloadnode.CommandContext(ctx2, robotCmd)
	defer cmd1.Stop()
	e = cmd1.Run(robot)
	if e != nil {
		log.Info("grafana ", zap.String("result", e.Error()))
	}

	cmdStr := fmt.Sprintf("grep fail /root/wkload/precheck/ui_pre_result.txt")
	cmd1 = workloadnode.CommandContext(ctx2, cmdStr)
	defer cmd1.Stop()
	e = cmd1.Run(robot)
	if e != nil {
		log.Info("grep fail for ui test ", zap.String("result", e.Error()))
	}
}

func API_Prometheus(
	ctx core.TestContext,
	workloadNode resource.WorkloadNode,
	cluster *TiUPCluster,
) {
	pmURL := matcher.Try(cluster.ServiceURL(resource.Prometheus)).(*url.URL)
	robot := ctx.Resource("wkload").(resource.WorkloadNode)
	duration := 10 * time.Hour
	ctx2, cancel := context.WithTimeout(ctx, duration)
	defer cancel()
	pdLead, _, _, err := workloadNode.Exec(resource.WorkloadNodeExecOptions{Command: "tiup cluster display debug | awk '$6 ~ /L/ {print $1}'"}) // 直接用
	if err != nil {
		log.Fatal("err info:", zap.String("cmd exec fail:", err.Error()))
	}
	log.Info("prometheus ", zap.String("dsn:", pdLead), zap.String("prometheus:", pmURL.Host))
	Cmd := fmt.Sprintf("sed -i 's/172.16.5.101:9090/%s/g' /upgrade-test/config.toml", pmURL.Host)
	cmd1 := workloadnode.CommandContext(ctx2, Cmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	pdIP := strings.Split(pdLead, ":")[0]
	pdPort := strings.Split(pdLead, ":")[1]

	Cmd = fmt.Sprintf("sed -i 's/172.16.5.101/%s/g' /upgrade-test/config.toml", pdIP)
	cmd1 = workloadnode.CommandContext(ctx2, Cmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	Cmd = fmt.Sprintf("sed -i 's/12379/%s/g' /upgrade-test/config.toml", pdPort)
	cmd1 = workloadnode.CommandContext(ctx2, Cmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())

	Cmd = fmt.Sprintf("cd /upgrade-test/API_TEST;python prometheus_api_test.py")
	cmd1 = workloadnode.CommandContext(ctx2, Cmd)
	defer cmd1.Stop()
	Expect(cmd1.Run(robot)).Should(BeNil())
}
