package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sort"
	"sync"
	"time"
)

const (
	maxLogSize    = 10 * 1024 * 1024 // 10MB
	maxLogFiles   = 5
	logFilePrefix = "lte_alarm"
)

var (
	logger         *log.Logger
	logFile        *os.File
	logMutex       sync.Mutex
	currentLogPath string
)

func initLogger(filename string) error {
	var err error
	currentLogPath = filename
	logFile, err = os.OpenFile(currentLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return fmt.Errorf("failed to open log file: %v", err)
	}

	logger = log.New(logFile, "", log.LstdFlags)
	return nil
}

func closeLogger() {
	if logFile != nil {
		logFile.Close()
	}
}

func logInfo(message string) {
	logMutex.Lock()
	defer logMutex.Unlock()

	if logger != nil {
		logger.Printf("INFO: %s", message)
		checkLogSize()
	}
	fmt.Println(message)
}

func logError(message string) {
	logMutex.Lock()
	defer logMutex.Unlock()

	if logger != nil {
		logger.Printf("ERROR: %s", message)
		checkLogSize()
	}
	fmt.Printf("ERROR: %s\n", message)
}

func checkLogSize() {
	info, err := logFile.Stat()
	if err != nil {
		fmt.Printf("Error checking log file size: %v\n", err)
		return
	}

	if info.Size() > maxLogSize {
		rotateLog()
	}
}

func rotateLog() {
	closeLogger()

	// Rename current log file
	timestamp := time.Now().Format("20060102_150405")
	newName := fmt.Sprintf("%s_%s.log", logFilePrefix, timestamp)
	err := os.Rename(currentLogPath, newName)
	if err != nil {
		fmt.Printf("Error renaming log file: %v\n", err)
		return
	}

	// Open new log file
	err = initLogger(currentLogPath)
	if err != nil {
		fmt.Printf("Error creating new log file: %v\n", err)
		return
	}

	// Clean up old log files
	cleanupOldLogs()
}

func cleanupOldLogs() {
	dir := filepath.Dir(currentLogPath)
	pattern := fmt.Sprintf("%s_*.log", logFilePrefix)
	matches, err := filepath.Glob(filepath.Join(dir, pattern))
	if err != nil {
		fmt.Printf("Error finding old log files: %v\n", err)
		return
	}

	if len(matches) <= maxLogFiles {
		return
	}

	sort.Slice(matches, func(i, j int) bool {
		return matches[i] > matches[j] // Sort in descending order
	})

	for _, file := range matches[maxLogFiles:] {
		err := os.Remove(file)
		if err != nil {
			fmt.Printf("Error removing old log file %s: %v\n", file, err)
		}
	}
}
