package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	_ "github.com/joho/godotenv/autoload"
	_ "github.com/mattn/go-sqlite3"
)

var (
	runStart = time.Now()
	logPath  = runStart.Format("2006-01-02.15:04:05") + ".gomeshalerter.json"
	logFile  *os.File
	logData  []LogEntry
	db       *sql.DB
	logMutex sync.Mutex // Mutex for thread-safe logging
)

func main() {
	fmt.Fprintf(os.Stderr, "[%s] starting gomeshalerter\n", runStart.Format("15:04:05"))
	setupLogging()
	defer flushLog()

	var err error
	db, err = sql.Open("sqlite3", dbPath+"?_journal=WAL") // Use WAL mode for better concurrency
	if err != nil {
		log.Fatalf("Failed to open database: %v", err)
	}

	// Define a cleanup function to properly close resources
	cleanup := func() {
		fmt.Fprintf(os.Stderr, "[shutdown] Closing database...\n")
		if err := db.Close(); err != nil {
			fmt.Fprintf(os.Stderr, "[shutdown] Error closing database: %v\n", err)
		}
		flushLog()
		fmt.Fprintf(os.Stderr, "[shutdown] Cleanup complete\n")
	}
	// Ensure cleanup runs on normal exit
	defer cleanup()

	if err := setupDatabase(); err != nil {
		log.Fatalf("Failed to setup database: %v", err)
	}

	ollamaModel := "qwen3:32b"
	ollamaURL := os.Getenv("OLLAMA_URL")
	if ollamaURL == "" {
		ollamaURL = "http://localhost:11434" // Default Ollama server URL
	}

	fmt.Fprintf(os.Stderr, "[ollama] Using model: %s at %s\n", ollamaModel, ollamaURL)

	// Replace --broadcast flag with --dry-run flag (default is to broadcast)
	dryRun := flag.Bool("dry-run", false, "don't actually send to meshtastic, just print what would be sent")
	flag.Parse()

	// Create a WaitGroup to manage goroutines
	var wg sync.WaitGroup

	// Create a channel to signal shutdown
	shutdown := make(chan struct{})

	// Set up signal handling for immediate exit with cleanup
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-sigChan
		fmt.Fprintf(os.Stderr, "[shutdown] Received signal, performing cleanup before exit...\n")
		cleanup()
		fmt.Fprintf(os.Stderr, "[shutdown] Exiting...\n")
		os.Exit(0) // Exit after cleanup
	}()

	// Start RSS feed checker goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		rssFeedChecker(shutdown, ollamaURL, ollamaModel)
	}()

	// Start article summarizer goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		articleSummarizer(shutdown, ollamaURL, ollamaModel)
	}()

	// Start broadcaster goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		broadcaster(shutdown, *dryRun)
	}()

	// Start web server goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		webServer(shutdown)
	}()

	// Start log cleanup worker goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		logCleanupWorker(shutdown)
	}()

	// Wait for all goroutines to finish
	wg.Wait()
	fmt.Fprintf(os.Stderr, "[shutdown] All goroutines stopped, exiting...\n")
}