package tiup_upgrade

import (
	"database/sql"
	"strings"

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

func PRIV_GRANT_001(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	Try(db.Query("create user qatest;"))
	Try(db.Query("grant Create on *.* to qatest;"))

}

func PRIV_GRANT_002(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	Try(db.Query("create database t;"))
	Try(db.Query("drop role if exists r1;"))
	Try(db.Query("create role r1;"))
	Try(db.Query("grant lock tables on t.* TO 'r1'@'%';"))
}

func PRIV_GRANT_003(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	Try(db.Query("create user test@'%';"))
	Try(db.Query("create role 'app_read';"))
	Try(db.Query("GRANT SYSTEM_VARIABLES_ADMIN, PROCESS on *.* to 'app_read'@'%';"))
	Try(db.Query("GRANT app_read to test;"))
	Try(db.Query("SET DEFAULT ROLE app_read TO 'test'@'%';"))
}

func PRIV_GRANT_004(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	var u string
	Try(db.QueryRow("show grants for qatest;").Scan(&u))
	log.Info("priv:", zap.String("info", u))
	u = strings.ToLower(u)
	Expect(u).Should(ContainSubstring("grant create on *.*"))

	Try(db.QueryRow("show grants for root;").Scan(&u))
	log.Info("priv:", zap.String("info", u))
	u = strings.ToLower(u)
	Expect(u).Should(ContainSubstring("grant all privileges on *.*"))

}

func PRIV_GRANT_005(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	var u string
	Try(db.QueryRow("show grants for r1;").Scan(&u))
	log.Info("priv:", zap.String("info", u))
	u = strings.ToLower(u)
	Expect(u).Should(ContainSubstring("grant usage on *.*"))
}

func PRIV_GRANT_006(
	cluster *TiUPCluster,
) {
	db := Try(cluster.GetDB("test")).(*sql.DB)
	defer db.Close()
	var u1, u2 string
	rows := Try(db.Query("show grants for test;")).(*sql.Rows)
	defer rows.Close()
	for rows.Next() {
		Try(rows.Scan(&u1))
		u2 += strings.ToLower(u1)
		log.Info("priv:", zap.String("info", u2))
	}
	Expect(u2).Should(ContainSubstring("grant usage on *.* to 'test'@'%'"))
	Expect(u2).Should(ContainSubstring("grant 'app_read'@'%' to 'test'@'%'"))
}
