package ccb_finance_test

import (
	"database/sql"
	"fmt"
	"strconv"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/pingcap/log"
	"github.com/pingcap/test-infra/sdk/resource"
	_ "github.com/pingcap/test-infra/sdk/resource/impl/k8s"
	"go.uber.org/zap"

	"github.com/pingcap/endless/pkg/client/tidb"
	"github.com/pingcap/endless/pkg/matcher"
	"github.com/pingcap/endless/testcase/tiflash/pkg"
)

const (
	schemaPath = "schema"
	queryPath  = "query"
	statsPath  = "./ccb-1020stats"
	dbName     = "fmta"
)

var _ = Describe("CcbFinance", func() {
	var (
		statsUrl         string
		lightningStorage string
		rounds           int
		tc               resource.TiDBCluster
		lightning        resource.Lightning
		db               *sql.DB
		tidbClient       *tidb.Client
	)
	BeforeEach(func() {
		lightning = suiteTestCtx.Resource("lightning").(resource.Lightning)
		tc = suiteTestCtx.Resource("tc").(resource.TiDBCluster)
		statsUrl = suiteTestCtx.Param("stats_url", "http://fileserver.pingcap.net/download/pingcap/qa/tiflash/ccb-1020stats.tar.gz")
		lightningStorage = suiteTestCtx.Param("lightning_storage", "s3://nfs/tiflash/ccb?access-key=minioadmin&secret-access-key=minioadmin&endpoint=http%3a%2f%2fminio.pingcap.net%3a9000&force-path-style=true")
		rounds = matcher.Try(strconv.Atoi(suiteTestCtx.Param("rounds", "10"))).(int)
	})
	Context("when execute ccb workload", func() {
		It("shouldn't fail", func() {
			tidbCli := tidb.NewClient(matcher.Try(tc.GetDB("")).(*sql.DB))
			if !matcher.Try(tidbCli.IsDBExist(suiteTestCtx, "fmta")).(bool) {
				cmd := pkg.GetLightningCmd(suiteTestCtx, tc, lightningStorage)
				matcher.Try(cmd.Run(lightning))
			}

			// https://pkg.go.dev/github.com/go-sql-driver/mysql#RegisterLocalFile
			db = matcher.Try(pkg.OpenDB(tc, dbName, pkg.MultiStatementsParam, pkg.AllowAllFilesParam)).(*sql.DB)
			tidbClient = tidb.NewClient(db)
			// schemaNames, schemas, err := pkg.ReadFileNamesAndContentsFromEmbedFs(schemaFs, schemaPath)
			// Expect(err).Should(BeNil())
			// for i, q := range schemas {
			// 	log.Info("create table", zap.String("table name", schemaNames[i]))
			// 	matcher.Try(tidbClient.Exec(q))
			// }

			tbls := matcher.Try(tidbClient.ShowTableNames(dbName)).([]string)
			matcher.Try(tidbClient.AlterBaseTablesSetTiFlashReplica(dbName, tbls, 2, ""))
			Eventually(func() bool {
				return matcher.Try(tidbClient.IsTiFlashReplicaAvailable(dbName, tbls)).(bool)
			}, 5*time.Minute, 3*time.Second).Should(BeTrue())

			matcher.Try(pkg.InstallArchive(suiteTestCtx, statsUrl, "./"))
			statNames := matcher.Try(pkg.ReadFileNamesFromDir(statsPath)).([]string)
			for _, name := range statNames {
				log.Info("load stats", zap.String("file name", name))
				matcher.Try(tidbClient.Exec(fmt.Sprintf("load stats '%s'", name)))
			}

			queryNames, queries, err := pkg.ReadFileNamesAndContentsFromEmbedFs(queryFS, queryPath)
			Expect(err).Should(BeNil())
			for r := 0; r < rounds; r++ {
				for i, q := range queries {
					_, count, err := pkg.Query(suiteTestCtx, db, q, true)
					log.Info("execute sql", zap.String("sql name", queryNames[i]), zap.Int("count", count))
					Expect(err).Should(BeNil())
				}
			}
		})
	})
})
