package cluster

import (
	"github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/tidbcloud/infra-api/pkg/config"
	"github.com/tidbcloud/infra-api/pkg/consts"
)

const (
	semSetupSQL = `CREATE USER cloud_admin;
GRANT BACKUP_ADMIN, RESTORE_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT DASHBOARD_CLIENT on *.* TO 'cloud_admin'@'%';
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT CONNECTION_ADMIN ON *.* TO 'cloud_admin'@'%';

GRANT RESTRICTED_VARIABLES_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT RESTRICTED_STATUS_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT RESTRICTED_CONNECTION_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT RESTRICTED_USER_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT RESTRICTED_TABLES_ADMIN ON *.* TO 'cloud_admin'@'%';
GRANT RESTRICTED_REPLICA_WRITER_ADMIN ON *.* TO 'cloud_admin'@'%';

GRANT CREATE USER ON *.* TO 'cloud_admin'@'%';
GRANT RELOAD ON *.* TO 'cloud_admin'@'%';
GRANT PROCESS ON *.* TO 'cloud_admin'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE ON mysql.* TO 'cloud_admin'@'%';
GRANT SELECT ON information_schema.* TO 'cloud_admin'@'%';
GRANT SELECT ON performance_schema.* TO 'cloud_admin'@'%';
GRANT SHOW DATABASES on *.* TO 'cloud_admin'@'%';

# Cross region requires these permissions, See https://docs.pingcap.com/tidb/stable/troubleshoot-ticdc/#when-the-sink-of-the-replication-downstream-is-tidb-or-mysql-what-permissions-do-users-of-the-downstream-database-need for more detail
GRANT SELECT ON *.* TO 'cloud_admin'@'%';
GRANT INDEX ON *.* TO 'cloud_admin'@'%';
GRANT INSERT ON *.* TO 'cloud_admin'@'%';
GRANT UPDATE ON *.* TO 'cloud_admin'@'%';
GRANT DELETE ON *.* TO 'cloud_admin'@'%';
GRANT CREATE ON *.* TO 'cloud_admin'@'%';
GRANT DROP ON *.* TO 'cloud_admin'@'%';
GRANT ALTER ON *.* TO 'cloud_admin'@'%';
GRANT CREATE VIEW ON *.* TO 'cloud_admin'@'%';

GRANT SHUTDOWN, CONFIG ON *.* TO 'cloud_admin'@'%';
REVOKE SHUTDOWN, CONFIG ON *.* FROM root;
`

	initSQL = `SET GLOBAL tidb_redact_log = 1;`

	analyzeSQL = `SET GLOBAL tidb_analyze_version = 1;`
)

// NewDefaultTidbInitializer creates a TidbInitializer for a tidb cluster named `db`
// For newly created cluster >= 5.3, enableSEM should set to true
// and cluster >= 5.1.0, enableAnalyze should set to true
func NewDefaultTidbInitializer(namespace string, enableSEM bool, enableAnalyze bool, experimentalEnabling string) *v1alpha1.TidbInitializer {
	pullIfNotPresent := corev1.PullIfNotPresent
	name := getInitializerName(consts.ClusterPrefix)
	// If tidb_analyze_version is set to 2 in experimentalEnabling, version 1 set by analyzeSQL will be overwritten.
	initsql := initSQL + "\n" + experimentalEnabling
	if enableSEM {
		initsql = semSetupSQL + "\n" + initsql
	}
	if enableAnalyze {
		initsql = analyzeSQL + "\n" + initsql
	}
	return &v1alpha1.TidbInitializer{
		ObjectMeta: metav1.ObjectMeta{
			Namespace: namespace,
			Name:      name,
		},
		Spec: v1alpha1.TidbInitializerSpec{
			Clusters:        v1alpha1.TidbClusterRef{Namespace: namespace, Name: consts.ClusterPrefix},
			InitSql:         &initsql,
			Image:           config.GetMysqlClientImage(),
			ImagePullPolicy: &pullIfNotPresent,
		},
	}
}
