package cvt

import (
	"fmt"

	opapiv1beta1 "github.com/tidbcloud/metrics-integration/global/api/integration/openapi/v1beta1"
	consolev1 "github.com/tidbcloud/metrics-integration/global/api/integration/v1"
	"github.com/tidbcloud/metrics-integration/global/internal/domain/entity"
)

// This file contains mapper functions between the rest layer and the database layer.
// These boilerplate functions have only one purpose -- static type safety.

func DatadogSiteDBToConsoleAPI(site entity.DatadogSite) consolev1.DatadogSite {
	var s consolev1.DatadogSite
	switch site {
	case entity.DatadogSiteUS1:
		s = consolev1.DatadogSite_DATADOG_SITE_US1
	case entity.DatadogSiteUS3:
		s = consolev1.DatadogSite_DATADOG_SITE_US3
	case entity.DatadogSiteUS5:
		s = consolev1.DatadogSite_DATADOG_SITE_US5
	case entity.DatadogSiteEU1:
		s = consolev1.DatadogSite_DATADOG_SITE_EU1
	case entity.DatadogSiteUS1FED:
		s = consolev1.DatadogSite_DATADOG_SITE_US1_FED
	case entity.DatadogSiteAP1:
		s = consolev1.DatadogSite_DATADOG_SITE_AP1
	default:
		s = consolev1.DatadogSite_DATADOG_SITE_UNSPECIFIED
	}
	return s
}

func NewrelicSiteDBToConsoleAPI(site entity.NewrelicSite) consolev1.NewrelicSite {
	var s consolev1.NewrelicSite
	switch site {
	case entity.NewrelicSiteEUOTLP:
		s = consolev1.NewrelicSite_NEWRELIC_SITE_EU_OTLP
	case entity.NewrelicSiteUSOTLP:
		s = consolev1.NewrelicSite_NEWRELIC_SITE_US_OTLP
	default:
		s = consolev1.NewrelicSite_NEWRELIC_SITE_UNSPECIFIED
	}
	return s
}

func DatadogSiteDBToOpenAPI(site entity.DatadogSite) opapiv1beta1.DatadogSite {
	var s opapiv1beta1.DatadogSite
	switch site {
	case entity.DatadogSiteUS1:
		s = opapiv1beta1.DatadogSite_US1
	case entity.DatadogSiteUS3:
		s = opapiv1beta1.DatadogSite_US3
	case entity.DatadogSiteUS5:
		s = opapiv1beta1.DatadogSite_US5
	case entity.DatadogSiteEU1:
		s = opapiv1beta1.DatadogSite_EU1
	case entity.DatadogSiteUS1FED:
		s = opapiv1beta1.DatadogSite_US1_FED
	case entity.DatadogSiteAP1:
		s = opapiv1beta1.DatadogSite_AP1
	default:
		s = opapiv1beta1.DatadogSite_DATADOG_SITE_UNSPECIFIED
	}
	return s
}

func NewrelicSiteDBToOpenAPI(site entity.NewrelicSite) opapiv1beta1.NewrelicSite {
	var s opapiv1beta1.NewrelicSite
	switch site {
	case entity.NewrelicSiteEUOTLP:
		s = opapiv1beta1.NewrelicSite_EU_OTLP
	case entity.NewrelicSiteUSOTLP:
		s = opapiv1beta1.NewrelicSite_US_OTLP
	default:
		s = opapiv1beta1.NewrelicSite_NEWRELIC_SITE_UNSPECIFIED
	}
	return s
}

func DatadogSiteConsoleAPIToDB(site consolev1.DatadogSite) entity.DatadogSite {
	var s entity.DatadogSite
	switch site {
	case consolev1.DatadogSite_DATADOG_SITE_US1:
		s = entity.DatadogSiteUS1
	case consolev1.DatadogSite_DATADOG_SITE_US3:
		s = entity.DatadogSiteUS3
	case consolev1.DatadogSite_DATADOG_SITE_US5:
		s = entity.DatadogSiteUS5
	case consolev1.DatadogSite_DATADOG_SITE_EU1:
		s = entity.DatadogSiteEU1
	case consolev1.DatadogSite_DATADOG_SITE_US1_FED:
		s = entity.DatadogSiteUS1FED
	case consolev1.DatadogSite_DATADOG_SITE_AP1:
		s = entity.DatadogSiteAP1

	default:
		s = entity.DatadogSiteUnspecified
	}
	return s
}

func DatadogSiteOpAPIToDB(site opapiv1beta1.DatadogSite) entity.DatadogSite {
	var s entity.DatadogSite
	switch site {
	case opapiv1beta1.DatadogSite_US1:
		s = entity.DatadogSiteUS1
	case opapiv1beta1.DatadogSite_US3:
		s = entity.DatadogSiteUS3
	case opapiv1beta1.DatadogSite_US5:
		s = entity.DatadogSiteUS5
	case opapiv1beta1.DatadogSite_EU1:
		s = entity.DatadogSiteEU1
	case opapiv1beta1.DatadogSite_US1_FED:
		s = entity.DatadogSiteUS1FED
	case opapiv1beta1.DatadogSite_AP1:
		s = entity.DatadogSiteAP1

	default:
		s = entity.DatadogSiteUnspecified
	}
	return s
}

func NewrelicSiteConsoleAPIToDB(site consolev1.NewrelicSite) entity.NewrelicSite {
	var s entity.NewrelicSite
	switch site {
	case consolev1.NewrelicSite_NEWRELIC_SITE_EU_OTLP:
		s = entity.NewrelicSiteEUOTLP
	case consolev1.NewrelicSite_NEWRELIC_SITE_US_OTLP:
		s = entity.NewrelicSiteUSOTLP
	default:
		s = entity.NewrelicSiteUnspecified
	}
	return s
}

func NewrelicSiteOpAPIToDB(site opapiv1beta1.NewrelicSite) entity.NewrelicSite {
	var s entity.NewrelicSite
	switch site {
	case opapiv1beta1.NewrelicSite_EU_OTLP:
		s = entity.NewrelicSiteEUOTLP
	case opapiv1beta1.NewrelicSite_US_OTLP:
		s = entity.NewrelicSiteUSOTLP
	default:
		s = entity.NewrelicSiteUnspecified
	}
	return s
}

func TypeConsoleAPIToDB(t consolev1.IntegrationType) entity.IntegrationType {
	var tDB entity.IntegrationType
	switch t {
	case consolev1.IntegrationType_INTEGRATION_TYPE_DATADOG:
		tDB = entity.IntegrationTypeDatadog
	case consolev1.IntegrationType_INTEGRATION_TYPE_PROMETHEUS:
		tDB = entity.IntegrationTypePrometheus
	case consolev1.IntegrationType_INTEGRATION_TYPE_NEWRELIC:
		tDB = entity.IntegrationTypeNewrelic
	default:
		tDB = entity.IntegrationTypeUnspecified
	}
	return tDB
}

func TypeDBToConsoleAPI(t entity.IntegrationType) consolev1.IntegrationType {
	var tRest consolev1.IntegrationType
	switch t {
	case entity.IntegrationTypeDatadog:
		tRest = consolev1.IntegrationType_INTEGRATION_TYPE_DATADOG
	case entity.IntegrationTypePrometheus:
		tRest = consolev1.IntegrationType_INTEGRATION_TYPE_PROMETHEUS
	case entity.IntegrationTypeNewrelic:
		tRest = consolev1.IntegrationType_INTEGRATION_TYPE_NEWRELIC
	default:
		tRest = consolev1.IntegrationType_INTEGRATION_TYPE_UNSPECIFIED
	}
	return tRest
}

func TypeDBToOpenAPI(t entity.IntegrationType) opapiv1beta1.IntegrationType {
	var tRest opapiv1beta1.IntegrationType
	switch t {
	case entity.IntegrationTypeDatadog:
		tRest = opapiv1beta1.IntegrationType_DATADOG
	case entity.IntegrationTypePrometheus:
		tRest = opapiv1beta1.IntegrationType_PROMETHEUS
	case entity.IntegrationTypeNewrelic:
		tRest = opapiv1beta1.IntegrationType_NEWRELIC
	default:
		tRest = opapiv1beta1.IntegrationType_INTEGRATION_TYPE_UNSPECIFIED
	}
	return tRest
}

func StatusDBToConsoleAPI(s entity.IntegrationStatus) consolev1.IntegrationStatus {
	var sRest consolev1.IntegrationStatus
	switch s {
	case entity.IntegrationStatusActive:
		sRest = consolev1.IntegrationStatus_INTEGRATION_STATUS_ACTIVE
	case entity.IntegrationStatusError:
		sRest = consolev1.IntegrationStatus_INTEGRATION_STATUS_ERROR
	case entity.IntegrationStatusNone:
		sRest = consolev1.IntegrationStatus_INTEGRATION_STATUS_NONE
	default:
		sRest = consolev1.IntegrationStatus_INTEGRATION_STATUS_UNSPECIFIED
	}
	return sRest
}

func StatusDBToOpenAPIState(s entity.IntegrationStatus) opapiv1beta1.IntegrationState {
	var sRest opapiv1beta1.IntegrationState
	switch s {
	case entity.IntegrationStatusActive:
		sRest = opapiv1beta1.IntegrationState_ACTIVE
	case entity.IntegrationStatusError:
		sRest = opapiv1beta1.IntegrationState_ERROR
	case entity.IntegrationStatusNone:
		sRest = opapiv1beta1.IntegrationState_NONE
	default:
		sRest = opapiv1beta1.IntegrationState_INTEGRATION_STATE_UNSPECIFIED
	}
	return sRest
}

func GetDatadogSiteUrl(site entity.DatadogSite) string {
	// DatadogSiteUrl refers to [https://github.com/DataDog/datadog-agent/blob/main/pkg/config/config_template.yaml]
	switch site {
	case entity.DatadogSiteUS1:
		return "datadoghq.com"
	case entity.DatadogSiteUS3:
		return "us3.datadoghq.com"
	case entity.DatadogSiteUS5:
		return "us5.datadoghq.com"
	case entity.DatadogSiteEU1:
		return "datadoghq.eu"
	case entity.DatadogSiteUS1FED:
		return "ddog-gov.com"
	case entity.DatadogSiteAP1:
		return "ap1.datadoghq.com"
	default:
		return "datadoghq.com"
	}
}

// GetDatadogDashboardUrl hardcodes the `TiDBCloud Integration dashboard` url.
func GetDatadogDashboardUrl(site entity.DatadogSite) string {
	var (
		authority     string
		integrationID int
	)
	// get dashboard id:
	// https://ap1.datadoghq.com/api/ui/app_listings/tidb-cloud
	switch site {
	case entity.DatadogSiteUS1:
		authority = "app.datadoghq.com"
		integrationID = 32021
	case entity.DatadogSiteUS3:
		authority = "us3.datadoghq.com"
		integrationID = 3153
	case entity.DatadogSiteUS5:
		authority = "us5.datadoghq.com"
		integrationID = 1797
	case entity.DatadogSiteEU1:
		authority = "app.datadoghq.eu"
		integrationID = 1749
	case entity.DatadogSiteAP1:
		authority = "ap1.datadoghq.com"
		integrationID = 3606
	case entity.DatadogSiteAP2:
		authority = "ap2.datadoghq.com"
		integrationID = 1978
	default:
		authority = "app.datadoghq.com"
		integrationID = 32021
	}
	return fmt.Sprintf("https://%s/dash/integration/%d/tidb-cloud-dynamic-tracker", authority, integrationID)
}

func GetNewrelicSiteEndpoint(site entity.NewrelicSite) string {
	// DatadogSiteUrl refers to [https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/#direct-export]
	switch site {
	case entity.NewrelicSiteEUOTLP:
		return "https://otlp.eu01.nr-data.net:443"
	case entity.NewrelicSiteUSOTLP:
		return "https://otlp.nr-data.net:443"
	default:
		return "https://otlp.nr-data.net:443"
	}
}

// GetNewrelicSiteDashboard returns the endpoint of the Newrelic dashboard·
func GetNewrelicSiteDashboard(site entity.NewrelicSite) string {
	return "https://one.newrelic.com/dashboards/"
}

func GetNewrelicSiteLogEp(site entity.NewrelicSite) string {
	// DatadogSiteUrl refers to [https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/#direct-export]
	switch site {
	case entity.NewrelicSiteEUOTLP:
		return "https://log-api.eu.newrelic.com/log/v1"
	case entity.NewrelicSiteUSOTLP:
		return "https://log-api.newrelic.com/log/v1"
	default:
		return "https://log-api.newrelic.com/log/v1"
	}
}

func OpenAPIDatadogStateToConsoleAPIState(s opapiv1beta1.IntegrationState) consolev1.IntegrationStatus {
	var state consolev1.IntegrationStatus
	switch s {
	case opapiv1beta1.IntegrationState_ACTIVE:
		state = consolev1.IntegrationStatus_INTEGRATION_STATUS_ACTIVE
	case opapiv1beta1.IntegrationState_ERROR:
		state = consolev1.IntegrationStatus_INTEGRATION_STATUS_ERROR
	case opapiv1beta1.IntegrationState_NONE:
		state = consolev1.IntegrationStatus_INTEGRATION_STATUS_NONE
	default:
		state = consolev1.IntegrationStatus_INTEGRATION_STATUS_UNSPECIFIED
	}
	return state
}

func OpenAPINewrelicStateToConsoleAPIState(s opapiv1beta1.IntegrationState) consolev1.IntegrationStatus {
	return OpenAPIDatadogStateToConsoleAPIState(s)
}
