package agent_deploy

import (
	"os"
	image2 "wdd.io/agent-common/image"
	"wdd.io/agent-common/logger"
	"wdd.io/agent-common/utils"
	"wdd.io/agent-deploy/a_dashboard"
	"wdd.io/agent-deploy/b_nfs"
	"wdd.io/agent-deploy/c_middle"
	"wdd.io/agent-deploy/d_app"
	"wdd.io/agent-deploy/e_cmii"
	"wdd.io/agent-deploy/z_dep"
)

var log = logger.Log

const (
	dev          = "uavcloud-dev"
	devFlight    = "uavcloud-devflight"
	devOperation = "uavcloud-devoperation"
	validation   = "uavcloud-feature"
	integration  = "uavcloud-test"
	uat          = "uavcloud-uat"
	demo         = "uavcloud-demo"
	uavms        = "uavcloud-uavms"
)

func OctopusDeploy() {

	// common environment
	common := &z_dep.CommonEnvironmentConfig{
		WebIP:                       "10.250.0.110",
		WebPort:                     "8888",
		HarborIPOrCustomImagePrefix: "10.250.0.110",
		HarborPort:                  "8033",
		Namespace:                   "bjtg",
		TagVersion:                  "5.5.0",
		TenantEnv:                   "",
		MinioPublicIP:               "10.250.0.110",
		MinioInnerIP:                "10.250.0.110",
		NFSServerIP:                 "10.250.0.110",
	}

	// kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
	a_dashboard.K8sDashboardDeploy(common)

	b_nfs.NFSDeploy(common)
	b_nfs.NFSTestDeploy(common)

	// pvc
	c_middle.PVCDeploy(common)

	// middlewares
	c_middle.MidMySQlDeploy(common)
	c_middle.MidRedisDeploy(common)
	c_middle.MidEmqxDeploy(common)
	c_middle.MidMongoDeploy(common)
	c_middle.MidRabbitMQDeploy(common)
	c_middle.MidRabbitMQDeploy(common)
	c_middle.MidNacosDeploy(common)

	configMapDeploy(common)
	d_app.IngressDeploy(common)

	gzipFilePrefix := "/root/octopus_image/xjyd/"
	frontendImageVersionMap, backendImageVersionMap, _ := image2.GzipFolderPathToCmiiImageTagMaps(gzipFilePrefix)

	doDeployBackend(common, backendImageVersionMap)
	doDeployFrontend(common, frontendImageVersionMap)
	d_app.SRSDeploy(common)
}

func CmiiAppDeploy() {

	// common environment
	common := &z_dep.CommonEnvironmentConfig{
		WebIP:                       "36.133.201.78",
		WebPort:                     "8888",
		HarborIPOrCustomImagePrefix: "192.168.0.14",
		HarborPort:                  "",
		Namespace:                   "xjyd",
		TagVersion:                  "5.5.0",
		TenantEnv:                   "",
		MinioPublicIP:               "36.133.201.146",
		MinioInnerIP:                "192.168.0.21",
		NFSServerIP:                 "192.168.0.14",
	}

	//frontendImageVersionMap, backendImageVersionMap, _ := image.FrontendBackendSrsImageMapFromCmiiImageMap(zjjt.CmiiImageMap)
	gzipFilePrefix := "/root/octopus_image/xjyd/"
	frontendImageVersionMap, backendImageVersionMap, _ := image2.GzipFolderPathToCmiiImageTagMaps(gzipFilePrefix)

	doDeployBackend(common, backendImageVersionMap)
	doDeployFrontend(common, frontendImageVersionMap)
	//utils.BeautifulPrint(frontendImageVersionMap)

	//configMapDeploy(common)
	//c_app.IngressDeploy(common)

}

func doDeployBackend(common *z_dep.CommonEnvironmentConfig, backendImageVersionMap map[string]string) {

	os.Remove(z_dep.BackendApplyFilePath)

	for appName, tag := range backendImageVersionMap {
		d_app.DefaultCmiiBackendConfig.AppName = appName
		d_app.DefaultCmiiBackendConfig.ImageTag = tag

		// ignore some app
		_, ok := d_app.IgnoreCmiiBackendAppName[appName]
		if ok {
			d_app.DefaultCmiiBackendConfig.Replicas = "0"
		} else {
			d_app.DefaultCmiiBackendConfig.Replicas = "1"
		}

		d_app.DefaultCmiiBackendConfig.BackendDeploy(common)
	}
}

func doDeployFrontend(common *z_dep.CommonEnvironmentConfig, frontendImageVersionMap map[string]string) {

	os.Remove(z_dep.FrontendApplyFilePath)

	d_app.FrontendDefaultNginxDeploy(common)

	for appName, tag := range frontendImageVersionMap {
		d_app.DefaultCmiiFrontendConfig.AppName = appName
		d_app.DefaultCmiiFrontendConfig.ImageTag = tag

		// ignore some app
		_, ok := d_app.IgnoreCmiiFrontendAppName[appName]
		if ok {
			d_app.DefaultCmiiFrontendConfig.Replicas = "0"
		} else {
			d_app.DefaultCmiiFrontendConfig.Replicas = "1"
		}

		value, ok := d_app.FrontendShortNameMaps[appName]
		if !ok {
			log.ErrorF("FrontendShortNameMaps error !  not contains %s", appName)
			continue
		}

		d_app.DefaultCmiiFrontendConfig.ShortName = value

		d_app.DefaultCmiiFrontendConfig.FrontendDeploy(common)
	}
}

func configMapDeploy(common *z_dep.CommonEnvironmentConfig) {
	os.Remove(z_dep.ConfigMapApplyFilePath)

	for frontendName, shortName := range d_app.FrontendShortNameMaps {
		d_app.DefaultCmiiFrontendConfig.AppName = frontendName
		d_app.DefaultCmiiFrontendConfig.ShortName = shortName

		value, ok := d_app.FrontendClientIdMaps[frontendName]
		if !ok {
			log.ErrorF("FrontendClientIdMaps error !  not contains %s", frontendName)
			continue
		}

		d_app.DefaultCmiiFrontendConfig.ClientId = value

		d_app.DefaultCmiiFrontendConfig.ConfigMapDeploy(common)
	}
}

// CmiiEnvironmentDeploy 部署完整的CMII环境的所有组件
func CmiiEnvironmentDeploy(isCompleteDeploy bool, commonEnv *z_dep.CommonEnvironmentConfig, backendImageVersionMap, frontendImageVersionMap map[string]string) {

	// clear old apply file
	_ = os.Mkdir(commonEnv.ApplyFilePrefix, os.ModePerm)

	oldApplyFileFolder := commonEnv.ApplyFilePrefix + "old"
	utils.RemoveFolderComplete(oldApplyFileFolder)
	_ = os.Mkdir(oldApplyFileFolder, os.ModePerm)

	// move all apply file to old folder
	_ = utils.MoveFolerToAnother(commonEnv.ApplyFilePrefix, oldApplyFileFolder)

	// get cmii env config from namespace
	cmiiEnvConfig := getCmiiEnvConfigurationFromNamespace(commonEnv.Namespace)

	// generate

	// generate new apply file for specific environment
	if isCompleteDeploy {

		// dashboard
		a_dashboard.K8sDashboardDeploy(commonEnv)
		// nfs
		b_nfs.NFSDeploy(commonEnv)
		b_nfs.NFSTestDeploy(commonEnv)

		// pvc
		c_middle.PVCDeploy(commonEnv)

		// middlewares
		cmiiEnvConfig.MySQlConfig.MidMySQlDeploy(commonEnv)
		cmiiEnvConfig.RedisConfig.MidRedisDeploy(commonEnv)
		cmiiEnvConfig.EmqxConfig.MidEmqxDeploy(commonEnv)
		cmiiEnvConfig.MongoConfig.MidMongoDeploy(commonEnv)
		cmiiEnvConfig.RabbitMQConfig.MidRabbitMQDeploy(commonEnv)
		cmiiEnvConfig.NacosConfig.MidNacosDeploy(commonEnv)

	}

	// frontend
	configMapDeploy(commonEnv)
	d_app.DefaultIngressConfig.IngressDeploy(commonEnv)
	doDeployFrontend(commonEnv, frontendImageVersionMap)

	// backend
	doDeployBackend(commonEnv, backendImageVersionMap)

	// srs
	cmiiEnvConfig.CmiiSrsConfig.SRSDeploy(commonEnv)

}

func CmiiNewAppDeploy(commonEnv *z_dep.CommonEnvironmentConfig, backendImageVersionMap, frontendImageVersionMap map[string]string) {

	// get cmii env config from namespace
	//cmiiEnvConfig := getCmiiEnvConfigurationFromNamespace(commonEnv.Namespace)

	// frontend
	configMapDeploy(commonEnv)

	d_app.DefaultIngressConfig.IngressDeploy(commonEnv)

	// frontend
	doDeployFrontend(commonEnv, frontendImageVersionMap)

	// backend
	doDeployBackend(commonEnv, backendImageVersionMap)
}

func getCmiiEnvConfigurationFromNamespace(namespace string) *e_cmii.CmiiEnvConfig {
	switch namespace {
	case dev:
		return e_cmii.CmiiDevConfig
	case devFlight:
		return e_cmii.CmiiDevFlightConfig
	case devOperation:
		return e_cmii.CmiiDevOperationConfig
	case integration:
		return e_cmii.CmiiIntegrationConfig
	case uat:
		return e_cmii.CmiiUatConfig
	case validation:
		return e_cmii.CmiiValidationConfig
	case uavms:
		return e_cmii.CmiiDemoConfig
	default:
		return e_cmii.CmiiOutSideConfig
	}
}
