package migrate

import (
	"errors"
	"time"

	"github.com/pingcap/log"
	"github.com/tidbcloud/metrics-server/central/config"
	"github.com/tidbcloud/metrics-server/central/db/entity"
	"gorm.io/gorm"
)

func initCentralDBV2(db *gorm.DB) error {
	log.Info("[version2] init empty database with data")
	//create the tables in a empty database
	//it is 3 time faster than migrate model individually
	if err := db.AutoMigrate(entity.ModelsV2...); err != nil {
		return err
	}
	log.Info("[version2] after create database tables")

	err := db.Exec("insert into monitor_data_migration_cfgs(cfg_key, cfg_value, created_at, updated_at) values('datadogIntegrationMigrationCfg', '{\"status\": 1}', now(), now()),('thirdPartyPrometheusIntegrationMigrationCfg', '{\"status\": 1}', now(), now())").Error
	if err != nil {
		return err
	}

	log.Info("[version2] after init empty database with data")
	return nil
}

func initCentralDB(db *gorm.DB) error {
	log.Info("init empty database with data")
	//create the tables in a empty database
	//it is 3 time faster than migrate model individually
	if err := db.AutoMigrate(entity.Models...); err != nil {
		return err
	}
	log.Info("after create database tables")

	email := config.Global().ServerConfig.ManagementPortalInitUserEmail
	if email == nil || *email == "" {
		return errors.New("the first management portal user email is empty")
	}
	now := time.Now()
	quotas := []*entity.Quota{
		{
			ComponentName: entity.TiDB,
			Quota:         config.DefaultTidbQuota,
		},
		{
			ComponentName: entity.TiKV,
			Quota:         config.DefaultTikvQuota,
		},
		{
			ComponentName: entity.TiFlash,
			Quota:         config.DefaultTiflashQuota,
		},
	}

	managementPortalTenant := &entity.Tenant{
		Name:     "pingcap management portal",
		Alias:    "",
		Email:    *email,
		Country:  "CN",
		TimeZone: "0",
		Status:   "active",
		// use free trial to avoid send using tidb email
		Plan:          entity.TenantPlanFreeTrial,
		Kind:          "internal",
		AcceptService: true,
		Quotas:        quotas,
		Projects:      nil,
	}
	managementPortalTenant.ID = entity.PingCAPTenantID
	if err := db.Create(managementPortalTenant).Error; err != nil {
		return err
	}

	adminRole := &entity.Role{
		TenantID: entity.PingCAPTenantID,
		Name:     "admin",
		Privileges: entity.Privileges{Privileges: []entity.Privilege{
			{
				Resource:  "*",
				Operation: "*",
			},
		}},
	}
	if err := db.Create(adminRole).Error; err != nil {
		return err
	}

	admin := &entity.User{
		TenantID:    entity.PingCAPTenantID,
		Email:       *email,
		Status:      entity.UserStatusActive,
		InvitedAt:   &now,
		Job:         "sre",
		PhoneNumber: "",
		Roles:       []entity.Role{*adminRole},
		Role:        entity.UserRoleOwner,
	}
	if err := db.Create(admin).Error; err != nil {
		return err
	}

	project := &entity.Project{
		TenantID: entity.PingCAPTenantID,
		Name:     config.DefaultProjectName,
		Users:    []entity.User{*admin},
	}
	err := project.Create(db)
	if err != nil {
		return err
	}

	systemSetting := &entity.SystemSetting{
		Value: entity.SystemSettingValue{
			EnableDevTier: entity.EnableDevTier{
				EnableOnAws: true,
				EnableOnGcp: false,
			},
		},
	}
	if err := db.Create(systemSetting).Error; err != nil {
		return err
	}

	err = initProviders(db)
	if err != nil {
		return err
	}

	log.Info("after init empty database with data")
	return nil
}

var (
	awsCloudProvider = &entity.Provider{
		Name: "aws",
		Regions: []*entity.Region{
			{
				Name:        "us-west-2",
				DisplayName: "US-West-2 (Oregon)",
				Zones: []*entity.Zone{
					{
						Name:        "us-west-2a",
						DisplayName: "us-west-2a",
					},
					{
						Name:        "us-west-2b",
						DisplayName: "us-west-2b",
					},
					{
						Name:        "us-west-2c",
						DisplayName: "us-west-2c",
					},
				},
				Status:            entity.RegionStatusActive,
				DefaultBackupTime: "10:00",
			},
			{
				Name:        "us-east-1",
				DisplayName: "US-East-1 (Virginia)",
				Zones: []*entity.Zone{
					{
						Name:        "us-east-1a",
						DisplayName: "us-east-1a",
					},
					{
						Name:        "us-east-1b",
						DisplayName: "us-east-1b",
					},
					{
						Name:        "us-east-1c",
						DisplayName: "us-east-1c",
					},
				},
				Status:            entity.RegionStatusActive,
				DefaultBackupTime: "07:00",
			},
		},
		Status: entity.ProviderStatusActive,
	}

	gcpCloudProvider = &entity.Provider{
		Name: "gcp",
		Regions: []*entity.Region{
			{
				Name:        "us-west1",
				DisplayName: "US-West1 (Oregon)",
				Zones: []*entity.Zone{
					{
						Name:        "us-west1-a",
						DisplayName: "us-west1-a",
					},
					{
						Name:        "us-west1-b",
						DisplayName: "us-west1-b",
					},
					{
						Name:        "us-west1-c",
						DisplayName: "us-west1-c",
					},
				},
				Status:            entity.RegionStatusActive,
				DefaultBackupTime: "10:00",
			},
			{
				Name:        "us-west2",
				DisplayName: "US-West2 (Oregon)",
				Zones: []*entity.Zone{
					{
						Name:        "us-west2-a",
						DisplayName: "us-west2-a",
					},
					{
						Name:        "us-west2-b",
						DisplayName: "us-west2-b",
					},
					{
						Name:        "us-west2-c",
						DisplayName: "us-west2-c",
					},
				},
				Status:            entity.RegionStatusActive,
				DefaultBackupTime: "10:00",
			},
		},
		Status: entity.ProviderStatusActive,
	}
)

// init cloud providers and infra providers
func initProviders(db *gorm.DB) error {
	providers := []*entity.Provider{
		awsCloudProvider,
		gcpCloudProvider,
	}

	if err := db.Create(providers).Error; err != nil {
		return err
	}

	infraProviders := []*entity.InfraProvider{
		{
			Name:       "aws",
			DeployType: entity.DeployTypeDedicated,
			ProviderID: awsCloudProvider.ID,
		},
		{
			Name:       "gcp",
			DeployType: entity.DeployTypeDedicated,
			ProviderID: gcpCloudProvider.ID,
		},
		{
			Name:       "aws-free-tier",
			DeployType: entity.DeployTypeShared,
			ProviderID: awsCloudProvider.ID,
		},
	}

	return db.Create(infraProviders).Error
}
