package integration

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/metrics-integration/pipeline/internal/otel_collector/exporter/otlphttpexporter"
	"github.com/tidbcloud/metrics-integration/pipeline/internal/otel_collector/extension/taskqueue"
	"github.com/tidbcloud/metrics-integration/pipeline/internal/otel_collector/processor/thanos"
	"github.com/tidbcloud/metrics-integration/pipeline/internal/otel_collector/receiver/metadb"
	"go.opentelemetry.io/collector/confmap"
	"go.opentelemetry.io/collector/confmap/provider/fileprovider"
	"go.opentelemetry.io/collector/exporter"
	"go.opentelemetry.io/collector/exporter/debugexporter"
	"go.opentelemetry.io/collector/otelcol"
	"go.opentelemetry.io/collector/otelcol/otelcoltest"
	"go.opentelemetry.io/collector/processor"
	"go.opentelemetry.io/collector/receiver"
)

func TestOTelIntegration(t *testing.T) {
	if os.Getenv("KUBERNETES_SERVICE_HOST") == "" || os.Getenv("KUBERNETES_SERVICE_PORT") == "" {
		t.Skip("requires in-cluster kubernetes environment")
	}

	factories, err := otelcoltest.NopFactories()
	require.NoError(t, err)

	factories.Extensions[taskqueue.TypeStr] = taskqueue.NewFactory()

	receivers := []receiver.Factory{
		metadb.NewFactory(),
		//prometheusreceiver.NewFactory(),
	}
	for _, rcv := range factories.Receivers {
		receivers = append(receivers, rcv)
	}
	factories.Receivers, err = receiver.MakeFactoryMap(receivers...)
	require.NoError(t, err)

	// Enable the selected processors.
	processors := []processor.Factory{
		thanos.NewFactory(), // private component
	}
	for _, pr := range factories.Processors {
		processors = append(processors, pr)
	}
	factories.Processors, err = processor.MakeFactoryMap(processors...)
	require.NoError(t, err)

	exporters := []exporter.Factory{
		// vector.NewFactory(),
		otlphttpexporter.NewFactory(),
		debugexporter.NewFactory(),
	}
	for _, exp := range factories.Exporters {
		exporters = append(exporters, exp)
	}
	factories.Exporters, err = exporter.MakeFactoryMap(exporters...)
	require.NoError(t, err)

	collector, err := otelcol.NewCollector(otelcol.CollectorSettings{
		Factories: func() (otelcol.Factories, error) { return factories, nil },
		ConfigProviderSettings: otelcol.ConfigProviderSettings{
			ResolverSettings: confmap.ResolverSettings{
				URIs: []string{filepath.Join("testdata", "config.yaml")},
				ProviderFactories: []confmap.ProviderFactory{
					fileprovider.NewFactory(),
				},
			},
		},
	})
	require.NoError(t, err)

	runErrCh := make(chan error, 1)
	go func() {
		runErrCh <- collector.Run(context.Background())
	}()

	time.Sleep(10 * time.Second)
	fmt.Printf("starting shutdown")
	collector.Shutdown()
	select {
	case err := <-runErrCh:
		require.NoError(t, err)
	case <-time.After(30 * time.Second):
		t.Fatalf("collector.Run did not return within timeout")
	}
}
