package main

import (
	"context"
	"net/http"
	"os"
	"time"

	"github.com/pingcap/log"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/tidbcloud/observability/sli-reporter/slprober"
	"github.com/tidbcloud/observability/sli-reporter/sqs"
	"k8s.io/apimachinery/pkg/util/wait"
)

const (
	O11yServiceLevelProbeShortInterval = 10 * time.Second
	O11yServiceLevelProbeLongInterval  = 10 * time.Minute
)

func main() {
	sqs.InitSQSConfig()
	slprober.RegisterMetric()
	slprober.PrepareConfigInfo("./prober_config.yaml")
	//slprober.PrepareConfigInfo("cmd/prober_config.yaml") // for manual test
	slprober.PrepareToken()
	slprober.PrepareKubeClient()
	O11yProber := slprober.NewO11yServiceLevelProber()
	reg := slprober.RegisterMetric()
	//c := slprober.GetConfig()

	go func() {
		timer := time.NewTimer(10 * time.Second)
		for {
			timer.Reset(10 * time.Second)
			<-timer.C
			if err := sqs.SendSLAMessage(reg); err != nil {
				log.Error(err.Error())
			}
		}
	}()
	onStarted := func(ctx context.Context) {
		go wait.Forever(func() { O11yProber.ProbeObservabilityDedicatedPrometheus() }, O11yServiceLevelProbeShortInterval)
		go wait.Forever(func() { O11yProber.ProbeObservabilitySharedVMCluster() }, O11yServiceLevelProbeShortInterval)
		go wait.Forever(func() { O11yProber.ProbeObservabilitySharedLoki() }, O11yServiceLevelProbeShortInterval)
		go wait.Forever(func() { O11yProber.ProbeObservabilityPrometheusMetricsUploadDelay() }, O11yServiceLevelProbeShortInterval)
		go wait.Forever(func() { O11yProber.ObservabilityClusterControlAPI() }, O11yServiceLevelProbeLongInterval)
		if os.Getenv("ENV") == "prod" {
			go wait.Forever(func() { O11yProber.ProbeS3LogsUploadDelay() }, O11yServiceLevelProbeLongInterval)
			go wait.Forever(func() { O11yProber.ProbeS3MetricsUploadDelay() }, O11yServiceLevelProbeLongInterval)
		}
	}
	controllerCtx, cancel := context.WithCancel(context.Background())
	defer cancel()
	onStarted(controllerCtx)

	log.Info("start prometheus server")
	http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))
	//http.ListenAndServe(":8081", nil)
	server := &http.Server{
		Addr:              ":8081",
		ReadHeaderTimeout: 3 * time.Second,
	}

	err := server.ListenAndServe()
	if err != nil {
		log.Error(err.Error())
	}
}
