package migrate

import (
	"github.com/pingcap/log"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

var tables = []string{
	"CREATE TABLE IF NOT EXISTS `branches` (" +
		"  `id` varchar(191) NOT NULL," +
		"  `created_at` timestamp NOT NULL," +
		"  `updated_at` timestamp NULL DEFAULT NULL," +
		"  `deleted_time` timestamp NULL DEFAULT NULL," +
		"  `creation_finished_time` timestamp NULL DEFAULT NULL," +
		"  `tenant_id` bigint unsigned NOT NULL," +
		"  `project_id` bigint unsigned NOT NULL," +
		"  `created_by_id` bigint unsigned NOT NULL," +
		"  `cloud_provider_name` longtext NOT NULL," +
		"  `region_name` longtext," +
		"  `name` varchar(255) NOT NULL," +
		"  `status` enum('creating','running','deleted') NOT NULL," +
		"  `parent_branch_id` varchar(191) NOT NULL," +
		"  `main_branch_id` varchar(191) NOT NULL," +
		"  `encrypted_cloud_admin_pwd` varchar(1024) NOT NULL," +
		"  `salt` binary(8) DEFAULT NULL," +
		"  PRIMARY KEY (`id`)," +
		"  UNIQUE KEY `unique_name` (`name`,`main_branch_id`,(ifnull(`deleted_time`,_utf8mb4'0000-00-00 00:00:00')))," +
		"  KEY `idx_branches_parent_branch_id` (`parent_branch_id`)," +
		"  KEY `idx_branches_main_branch_id` (`main_branch_id`)," +
		"  KEY `idx_branches_project_id` (`project_id`)," +
		"  KEY `idx_branches_created_by_id` (`created_by_id`)" +
		")",

	"CREATE TABLE IF NOT EXISTS `clusters` (" +
		"  `id` bigint unsigned NOT NULL AUTO_INCREMENT," +
		"  `keyspace_id` bigint unsigned NOT NULL," +
		"  `tenant_id` bigint unsigned NOT NULL," +
		"  `project_id` bigint unsigned NOT NULL," +
		"  `cloud_provider_name` longtext NOT NULL," +
		"  `region_name` varchar(191) NOT NULL," +
		"  `created_time` timestamp NOT NULL," +
		"  `creation_finished_time` timestamp NULL DEFAULT NULL," +
		"  `spend_limit` decimal(20,2) NOT NULL," +
		"  `free_credit` decimal(20,2) NOT NULL," +
		"  `is_paid` tinyint(1) NOT NULL," +
		"  `canary_mark` tinyint(1) NOT NULL," +
		"  `updated_at` timestamp NULL DEFAULT NULL," +
		"  PRIMARY KEY (`id`)," +
		"  KEY `idx_clusters_keyspace_id` (`keyspace_id`)," +
		"  KEY `idx_clusters_region_name` (`region_name`)" +
		")",

	"CREATE TABLE IF NOT EXISTS `cluster_tidb_pools` (" +
		"  `event_id` bigint unsigned NOT NULL AUTO_INCREMENT," +
		"  `type` enum('spend_limit','canary') NOT NULL," +
		"  `cluster_id` bigint unsigned NOT NULL," +
		"  `project_id` bigint unsigned DEFAULT NULL," +
		"  `created_at` timestamp NOT NULL," +
		"  `updated_at` timestamp NULL DEFAULT NULL," +
		"  `spend_limit_status` longtext," +
		"  `canary_mark` tinyint(1) DEFAULT NULL," +
		"  `status` enum('synced','unsynced') NOT NULL," +
		"  PRIMARY KEY (`event_id`)," +
		"  KEY `idx_cluster_tidb_pools_cluster_id` (`cluster_id`)" +
		")",

	"CREATE TABLE IF NOT EXISTS `region_metering_records` (" +
		"  `id` bigint unsigned NOT NULL AUTO_INCREMENT," +
		"  `created_at` timestamp NOT NULL," +
		"  `region` varchar(32) NOT NULL," +
		"  `time_stamp` datetime(3) NOT NULL," +
		"  `type` varchar(191) NOT NULL," +
		"  PRIMARY KEY (`id`)," +
		"  KEY `idx_region_metering_records_region` (`region`)," +
		"  KEY `idx_region_metering_records_type` (`type`)" +
		")",

	"CREATE TABLE IF NOT EXISTS `downtimes` (" +
		"  `cluster_id` varchar(191) NOT NULL," +
		"  `down_time` timestamp NOT NULL," +
		"  `down_rate` decimal(20,2) NOT NULL," +
		"  `region` longtext NOT NULL," +
		"  `month` varchar(191) NOT NULL," +
		"  `updated_at` timestamp NOT NULL," +
		"  PRIMARY KEY (`cluster_id`,`down_time`)," +
		"  KEY `idx_month` (`month`)" +
		")",

	"CREATE TABLE IF NOT EXISTS `backups` (" +
		" `id` bigint unsigned NOT NULL AUTO_INCREMENT," +
		" `created_at` timestamp NOT NULL," +
		" `updated_at` timestamp NULL DEFAULT NULL," +
		" `deleted_at` timestamp NULL DEFAULT NULL," +
		" `region` varchar(64) NOT NULL," +
		" `name` varchar(255) NOT NULL," +
		" `backup_id` bigint unsigned NOT NULL," +
		" `backup_time` timestamp NOT NULL," +
		" PRIMARY KEY (`id`)," +
		" KEY `idx_region_time` (`region`,`backup_time`)" +
		")",

	"CREATE TABLE IF NOT EXISTS `project_canaries` (" +
		" `project_id` bigint unsigned NOT NULL," +
		" `created_at` timestamp NOT NULL," +
		" PRIMARY KEY (`project_id`)" +
		")",

	createBackupScheduleHistoriesSQL,
	createBackupTombstonesSQL,
	createBackupVirtualizationMetadataSQL,
	createPhysicalBackupSlotsSQL,
	// InitSchema marks all migrations as applied, so a fresh database must also
	// initialize the required cutover metadata here.
	initializeBackupVirtualizationCutoverSQL,
}

func initSchema(db *gorm.DB) error {
	log.Info("init empty database with tables")
	return db.Transaction(func(tx *gorm.DB) error {
		for _, table := range tables {
			err := tx.Exec(table).Error
			if err != nil {
				log.Error("failed to create table", zap.Error(err))
				return err
			}
		}

		log.Info("create database tables completed")
		return nil
	})
}
