package metadb

import (
	"context"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/tidbcloud/metrics-integration/pipeline/central/entity"
	"github.com/tidbcloud/metrics-integration/pipeline/internal/metadata"
	"go.opentelemetry.io/collector/component"
	"go.opentelemetry.io/collector/consumer"
	"go.opentelemetry.io/collector/receiver"
	"go.opentelemetry.io/collector/scraper"
	"go.opentelemetry.io/collector/scraper/scraperhelper"
)

var (
	ReceiverType = component.MustNewType("metadb")
)

var (
	receiverDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "otelcol_receiver_scrape_duration",
			Help:    "the time that used for scrape integration info from rds",
			Buckets: prometheus.ExponentialBuckets(0.05, 2, 8), // 50ms ~ 12.8s
		}, []string{"integration_type"})
)

func init() {
	prometheus.MustRegister(receiverDuration)
}

func NewFactory() receiver.Factory {
	return receiver.NewFactory(
		ReceiverType,
		createDefaultConfig,
		receiver.WithMetrics(createMetricsReceiver, component.StabilityLevelStable),
	)
}

type Config struct {
	scraperhelper.ControllerConfig `mapstructure:",squash"`
	metadata.MetricsBuilderConfig  `mapstructure:",squash"`
	//Integration                             Integration `mapstructure:"integration"`
	TaskQueueExtension component.ID `mapstructure:"taskqueue,omitempty"`
	EnableBackfill     bool         `mapstructure:"enable_backfill,omitempty"`
}

func createDefaultConfig() component.Config {
	return &Config{
		ControllerConfig: scraperhelper.ControllerConfig{
			//ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(typeStr)),
			// https://github.com/pingcap/tidb-operator/blob/master/charts/tidb-cluster/templates/config/_prometheus-config.tpl
			CollectionInterval: 15 * time.Second,
		},
		MetricsBuilderConfig: metadata.MetricsBuilderConfig{
			Metrics: metadata.MetricsConfig{
				TidbCloudDbActiveConnections: metadata.MetricConfig{
					Enabled: true,
				},
				TidbCloudNodeCPUCapacityCores: metadata.MetricConfig{
					Enabled: true,
				},
				TidbCloudNodeMemoryCapacityBytes: metadata.MetricConfig{
					Enabled: true,
				},
				TidbCloudNodeStorageCapacityBytes: metadata.MetricConfig{
					Enabled: true,
				},
				TidbCloudNodeMemoryUsedBytes: metadata.MetricConfig{
					Enabled: true,
				},
			},
		},
	}
}

func createMetricsReceiver(
	_ context.Context,
	params receiver.Settings,
	rConf component.Config,
	consumer consumer.Metrics,
) (receiver.Metrics, error) {
	cfg := rConf.(*Config)

	// We only support Datadog and newrelic integration for now.
	iTypes := make([]entity.IntegrationType, 0)

	// overide all resource attributes
	cfg.ResourceAttributes = metadata.ResourceAttributesConfig{
		ClusterID: metadata.ResourceAttributeConfig{
			Enabled: true,
		},
		ClusterName: metadata.ResourceAttributeConfig{
			Enabled: true,
		},
		ProjectID: metadata.ResourceAttributeConfig{
			Enabled: true,
		},
		ProjectName: metadata.ResourceAttributeConfig{
			Enabled: true,
		},
	}

	if !cfg.EnableBackfill {
		ns := newMetadbScraper(params.Logger, cfg, iTypes, params)
		s, err := scraper.NewMetrics(ns.scrape)
		if err != nil {
			return nil, err
		}

		return scraperhelper.NewScraperControllerReceiver(
			&cfg.ControllerConfig, params, consumer,
			scraperhelper.AddScraper(ReceiverType, s),
		)
	} else {
		return newmetadbReceiverWithTaskQueue(
			params.Logger,
			cfg,
			consumer,
			iTypes,
			params,
		)
	}
}
