package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"primesys_command_producer/src/config"
	"primesys_command_producer/src/db"
	"primesys_command_producer/src/kafka"
	"primesys_command_producer/src/logger"
	"primesys_command_producer/src/storage"
	"primesys_command_producer/src/websocket"
	"syscall"

	"github.com/joho/godotenv"
)

func main() {

	// dotenv package intitated
	err := godotenv.Load()

	if err != nil {
		log.Fatal("Env not loaded")
	}

	// env variables loaded
	cfg := config.Load()

	log.Println("Config Loaded...")

	// db connection loaded
	if err := db.DBConnect(cfg.MongoURI, cfg.MongoDBName); err != nil {
		logger.Fatal("Mongo connect failed: %v", err)
	}

	defer db.Disconnect()

	if err := storage.CheckCommandFile(); err != nil {
		log.Fatalf("failed to set up command.json: %v", err)
	}

	if err := storage.ClearQueue(); err != nil {
		logger.Error("Failed to clear queue: %v", err)
	}

	go storage.RunQueue(websocket.ProcessQueue)

	kafkaConsumer, err := kafka.NewKafkaConsumer(cfg.KafkaBrokers, cfg.KafkaGroupId, cfg.KafkaTopic)

	if err != nil {
		logger.Fatal("Kafka consumer initialization failed : %v", err)
	}

	defer kafkaConsumer.KafkaClose()

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()
	consumeDone := make(chan struct{})
	go func() {
		kafkaConsumer.Consume(ctx)
		close(consumeDone)
	}()
	logger.Info("Kafka Consumer started")

	go func() {
		if err := websocket.SocketServer(cfg.SocketAddr); err != nil {
			logger.Error("Socket server stopped: %v", err)
		}
	}()

	// wait for ctrl+c / kill, then let the read loop finish before the deferred KafkaClose
	<-ctx.Done()

	logger.Info("Shutting down..")
	<-consumeDone
}
