package tiup_upgrade

import (
	"database/sql"
	"strings"
	"time"

	. "github.com/pingcap/endless/pkg/matcher"

	. "github.com/onsi/ginkgo"
	. "github.com/pingcap/endless/pkg/workloadnode/tiup"
	"github.com/pingcap/log"
	"go.uber.org/zap"
)

type replica struct {
	table_schema    string
	table_name      string
	table_id        int
	replica_count   int
	location_labels string
	available       int
	progress        int
	table_mode      string
}

type paln struct {
	id            string
	estRows       float32
	task          string
	access_object string
	operator_info string
}

func TIFLASH_001(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	Try(db.Query("alter table bank.account SET TIFLASH REPLICA 1;"))
}

func TIFLASH_002(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	time.Sleep(60 * time.Second)
	defer db.Close()
	rows := Try(db.Query("SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = 'bank' and TABLE_NAME = 'account';")).(*sql.Rows)
	defer rows.Close()
	for rows.Next() {
		var r replica
		Try(rows.Scan(&r.table_schema, &r.table_name, &r.table_id, &r.replica_count, &r.location_labels, &r.available, &r.progress))
		log.Info("tiflash replica:", zap.Int("available", r.available), zap.Int("progress", r.progress))
		if r.available == 0 && r.progress == 0 {
			Fail("tiflash replica sync fail")
		}
	}

	rows = Try(db.Query("desc select count(*)  from bank.account;")).(*sql.Rows)
	defer rows.Close()
	i := 0
	for rows.Next() {
		var pl paln
		err := rows.Scan(&pl.id, &pl.estRows, &pl.task, &pl.access_object, &pl.operator_info)
		must(err)
		log.Info("query plan:", zap.String("task", string(pl.task)))
		if strings.Contains(pl.task, "tiflash") {
			i = i + 1
			break
		}
	}
	if i == 0 {
		Fail("plan not use tiflash")
	}

	var u int
	Try(db.QueryRow("select count(*) from bank.account;").Scan(&u))
	if u == 0 {
		Fail("query with tiflash fail")
	}

}

func TIFLASH_003(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	time.Sleep(60 * time.Second)
	defer db.Close()
	rows := Try(db.Query("SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = 'bank' and TABLE_NAME = 'account';")).(*sql.Rows)
	defer rows.Close()
	for rows.Next() {
		var r replica
		Try(rows.Scan(&r.table_schema, &r.table_name, &r.table_id, &r.replica_count, &r.location_labels, &r.available, &r.progress, &r.table_mode))
		log.Info("tiflash replica:", zap.Int("available", r.available), zap.Int("progress", r.progress))
		if r.available == 0 && r.progress == 0 {
			Fail("tiflash replica sync fail")
		}
	}

	rows = Try(db.Query("desc select count(*)  from bank.account;")).(*sql.Rows)
	defer rows.Close()
	i := 0
	for rows.Next() {
		var pl paln
		err := rows.Scan(&pl.id, &pl.estRows, &pl.task, &pl.access_object, &pl.operator_info)
		must(err)
		log.Info("query plan:", zap.String("task", string(pl.task)))
		if strings.Contains(pl.task, "tiflash") {
			i = i + 1
			break
		}
	}
	if i == 0 {
		Fail("plan not use tiflash")
	}

	var u int
	Try(db.QueryRow("select count(*) from bank.account;").Scan(&u))
	if u == 0 {
		Fail("query with tiflash fail")
	}

}
