package metrics

import (
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/tidbcloud/metrics-server/central/db/entity"
)

// CommonLabels define some common labels to help diagnose problems
var CommonLabels = []string{"tenant_id", "tenant_name", "cluster_id", "cluster_name"}

const (
	Unknown  = "unknown"
	DevTier  = "aws-free-tier"
	Dedicate = "dedicate"
	// ClusterLblName is the name of clusterID label.
	ClusterLblName  = "cluster_id"
	ProviderTypeLbl = "provider_type"
)

type Tenant struct {
	ID   entity.ID
	Name string
}

var (
	// ConnectMysqlErrorCounter collect counter of connecting db failed.
	ConnectMysqlErrorCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: "dbaas",
			Subsystem: "statistics",
			Name:      "connect_db_failed",
			Help:      "count of connecting db failed.",
		}, []string{ProviderTypeLbl})

	DevTierActiveClustersCount = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Namespace: "dbaas",
			Subsystem: "dev_tier",
			Name:      "active_clusters_count",
			Help:      "dev tier active clusters count.",
		}, []string{ProviderLblName, ProviderTypeLbl},
	)
)

// metric for backup/restore
var (
	TiDBClusterScaleDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Namespace: "dbaas",
		Subsystem: "tidb_cluster",
		Name:      "scale_duration_seconds",
		Help:      "Seconds time of using in scale in or out cluster",
		Buckets:   prometheus.ExponentialBuckets(2, 2, 20),
	}, []string{ProviderTypeLbl})

	ReplicationCreationDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: "dbaas",
			Subsystem: "replication",
			Name:      "creation_duration_seconds",
			Help:      "create time of create replication",
		}, []string{ProviderTypeLbl},
	)

	ReplicationPlannedDetachDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: "dbaas",
			Subsystem: "replication",
			Name:      "planned_detach_duration_seconds",
			Help:      "planned detach time of create replication",
		}, []string{ProviderTypeLbl},
	)

	ReplicationForceDetachDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: "dbaas",
			Subsystem: "replication",
			Name:      "force_detach_duration_seconds",
			Help:      "force detach time of create replication",
		}, []string{ProviderTypeLbl},
	)

	CreateClusterDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: "dbaas",
			Subsystem: "tidb_cluster",
			Name:      "create_duration",
			Help:      "Duration in seconds to create cluster",
			Buckets:   prometheus.ExponentialBuckets(10, 2, 11), // 10s~1h
		}, []string{ProviderTypeLbl},
	)
)

// metric for import
var (
	SyncingImportSinceCreatedSeconds = prometheus.NewDesc(
		prometheus.BuildFQName("dbaas", "import", "syncing_import_since_created_seconds"),
		"How long has the import been created still syncing",
		[]string{"tenant", ClusterLblName, "import_id", ProviderTypeLbl, "status"},
		nil)

	RecentFailImports = prometheus.NewDesc(
		prometheus.BuildFQName("dbaas", "import", "fail"),
		"Recent failed imports",
		[]string{"tenant", ClusterLblName, "import_id", ProviderTypeLbl, "msg"},
		nil)

	ImportThroughputBytes = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: "dbaas",
			Subsystem: "import",
			Name:      "throughput_bytes",
			Help:      "Import job throughput in bytes/s",
			Buckets:   prometheus.ExponentialBuckets(1024, 2, 22), //1KB/s-4GB/s
		}, []string{ProviderTypeLbl})
)

func RegisterMetrics() {
	prometheus.MustRegister(HttpRequestDuration)
	prometheus.MustRegister(NewUptimeCollector(time.Now().Unix()))
	prometheus.MustRegister(MetricsApiRequestErrCnt, MetricsApiRequestDuration)
}

func GetProviderType(free bool) string {
	if free {
		return DevTier
	}
	return Dedicate
}
