package controllers

import (
	"time"

	"github.com/pkg/errors"

	"github.com/fiskerinc/cloud-services/services/depot/services"

	"github.com/fiskerinc/cloud-services/pkg/health"
	"github.com/fiskerinc/cloud-services/pkg/logger"
)

var mismatchTypeError = errors.New("mismatch type error")

func HealthCheck() {
	redis := health.NewRedisHealth(services.RedisClientPool())
	server := health.HealthCheckServer{}
	err := server.Serve([]health.Config{
		{
			Name:    "db",
			Check:   health.NewPostgresCheck(services.GetDB().GetDBClient().GetConn()),
			Timeout: time.Second * 1,
		},
		{
			Name:    "redis",
			Check:   redis.Check,
			Timeout: time.Second * 1,
			Info:    redis.RedisStatus,
		},
		{
			Name:    "mongodb",
			Check:   health.NewMongoDBCheck(getMongoClient),
			Timeout: time.Second * 1,
		},
		{
			Name:    "kafka",
			Check:   health.NewKafkaMultiCheck(getKafkaConsumer),
			Timeout: time.Second * 1,
			Vital:   true,
		},
	})
	if err != nil {
		logger.Error().Err(err).Send()
	}
}

func getMongoClient() (health.MongoConnCheckInterface, error) {
	client, err := services.GetMongoClient()
	if err != nil {
		return nil, err
	}

	conn, ok := client.(health.MongoConnCheckInterface)
	if !ok {
		return nil, errors.WithStack(mismatchTypeError)
	}

	return conn, nil
}

func getKafkaConsumer() ([]health.KafkaConnCheckInterface, error) {
	var connections []health.KafkaConnCheckInterface
	client, oldClient, err := services.GetKafkaConsumer()
	if err != nil {
		return connections, err
	}
	conn, ok := client.(health.KafkaConnCheckInterface)
	if !ok {
		return nil, errors.WithStack(mismatchTypeError)
	}
	connections = append(connections, conn)

	oldConn, ok := oldClient.(health.KafkaConnCheckInterface)
	if !ok {
		return connections, errors.WithStack(mismatchTypeError)
	}
	connections = append(connections, oldConn)

	return connections, nil
}
