// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package functionality

import (
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/pingcap/endless/pkg/matcher"
	. "github.com/pingcap/endless/pkg/workload"
	. "github.com/pingcap/endless/testcase/geopartition/utils"
)

func clusteredIndexTest(ctx *SuiteContext) {
	It("clustered/no clustered index should work on placement tables", func() {
		defer func() {
			MustExec(ctx.DB, "DROP TABLE IF EXISTS t1,t2,t3,t4")
			MustExec(ctx.DB, "DROP PLACEMENT POLICY IF EXISTS p1")
		}()

		MustExec(ctx.DB, "DROP TABLE IF EXISTS t1,t2,t3,t4")
		MustExec(ctx.DB, "DROP PLACEMENT POLICY IF EXISTS p1")
		MustExec(ctx.DB, "CREATE PLACEMENT POLICY p1 LEADER_CONSTRAINTS=\"[+region=us-east-1]\" FOLLOWER_CONSTRAINTS=\"[+region=us-east-2]\"")
		MustExec(ctx.DB, "CREATE TABLE t1 (id BIGINT NOT NULL PRIMARY KEY auto_increment, b varchar(255)) PLACEMENT POLICY=p1")
		MustExec(ctx.DB, "INSERT INTO t1 values(1, 'vt1')")
		MustExec(ctx.DB, "CREATE TABLE t2 (id BIGINT NOT NULL, b varchar(255) PRIMARY KEY) PLACEMENT POLICY=p1")
		MustExec(ctx.DB, "INSERT INTO t2 values(2, 'vt2')")
		MustExec(ctx.DB, "CREATE TABLE t3 (id BIGINT NOT NULL AUTO_INCREMENT, b varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) /*T![clustered_index] NONCLUSTERED */) PLACEMENT POLICY=p1")
		MustExec(ctx.DB, "INSERT INTO t3 values(3, 'vt3')")
		MustExec(ctx.DB, "CREATE TABLE t4 (id BIGINT NOT NULL AUTO_INCREMENT, b varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */) PLACEMENT POLICY=p1")
		MustExec(ctx.DB, "INSERT INTO t4 values(4, 'vt4')")
		Expect(ReadAll(MustQuery(ctx.DB, "SELECT * from t1"))).
			Should(Equal([][]string{{"1", "vt1"}}))
		Expect(ReadAll(MustQuery(ctx.DB, "SELECT * from t2"))).
			Should(Equal([][]string{{"2", "vt2"}}))
		Expect(ReadAll(MustQuery(ctx.DB, "SELECT * from t3"))).
			Should(Equal([][]string{{"3", "vt3"}}))
		Expect(ReadAll(MustQuery(ctx.DB, "SELECT * from t4"))).
			Should(Equal([][]string{{"4", "vt4"}}))

		Try(WaitScheduled(ctx.DB, "t1", time.Minute))
		Try(WaitScheduled(ctx.DB, "t2", time.Minute))
		Try(WaitScheduled(ctx.DB, "t3", time.Minute))
		Try(WaitScheduled(ctx.DB, "t4", time.Minute))

		checkSchedule := func(tableName string) {
			CheckRegions(ctx, tableName, "", func(r Regions) {
				r.CheckLeaderPlacement("+region=us-east-1").
					CheckFollowerPlacement("+region=us-east-2", 2).
					CheckNoPeersLeft()
			})
		}
		checkSchedule("t1")
		checkSchedule("t2")
		checkSchedule("t3")
		checkSchedule("t4")
	})
}
