package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/fsnotify/fsnotify"
	"github.com/getsentry/sentry-go"
)

var debug bool

func main() {
	// Check if debug mode is enabled
	if os.Getenv("DEBUG") == "true" {
		debug = true
	}

	// Get the DSN from the environment
	dsn := os.Getenv("GLITCHTIP_DSN")
	if dsn == "" {
		fmt.Fprintf(os.Stderr, "Error: GLITCHTIP_DSN environment variable is not set.\n")
		os.Exit(1)
	}

	// Initialize Sentry
	err := sentry.Init(sentry.ClientOptions{
		Dsn: dsn,
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error initializing GlitchTip: %s\n", err)
		os.Exit(1)
	}
	defer sentry.Flush(2 * time.Second)

	// Get the log files from the environment
	logFilesEnv := os.Getenv("LOG_FILES")
	if logFilesEnv == "" {
		fmt.Fprintf(os.Stderr, "Error: LOG_FILES environment variable is not set.\n")
		os.Exit(1)
	}
	logFiles := strings.Split(logFilesEnv, ",")

	// Create a new file watcher
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating watcher: %s\n", err)
		os.Exit(1)
	}
	defer watcher.Close()

	// Add log files to the watcher
	for _, logFile := listFiles(logFiles) {
		if debug {
			fmt.Printf("Adding file to watcher: %s\n", logFile)
		}
		err = watcher.Add(logFile)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error adding file to watcher: %s\n", err)
			os.Exit(1)
		}
	}

	// Watch for file changes
	go func() {
		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					return
				}
				if event.Op&fsnotify.Write == fsnotify.Write {
					if debug {
						fmt.Printf("File modified: %s\n", event.Name)
					}
					processLogFile(event.Name)
				}
			case err, ok := <-watcher.Errors:
				if !ok {
					return
				}
				fmt.Fprintf(os.Stderr, "Watcher error: %s\n", err)
			}
		}
	}()

	// Block forever
	select {}
}

func processLogFile(filePath string) {
	if debug {
		fmt.Printf("Processing log file: %s\n", filePath)
	}
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error opening file: %s\n", err)
		return
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		if debug {
			fmt.Printf("Read line: %s\n", line)
		}
		if strings.Contains(strings.ToLower(line), "error") {
			sendToSentry(line)
		}
	}

	if err := scanner.Err(); err != nil {
		fmt.Fprintf(os.Stderr, "Error reading file: %s\n", err)
	}
}

func sendToSentry(message string) {
	if debug {
		fmt.Printf("Sending message to GlitchTip: %s\n", message)
	}
	sentry.CaptureMessage(message)
}

// Utility function to list log files
func listFiles(logFiles []string) []string {
	var validFiles []string
	for _, file := range logFiles {
		if _, err := os.Stat(file); err == nil {
			validFiles = append(validFiles, file)
		} else {
			fmt.Fprintf(os.Stderr, "Log file does not exist: %s\n", file)
		}
	}
	return validFiles
}
