package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime"
	"time"

	"git.mchus.pro/mchus/logpile/internal/parser"
	_ "git.mchus.pro/mchus/logpile/internal/parser/vendors" // Register all vendor parsers
	"git.mchus.pro/mchus/logpile/internal/server"
	"git.mchus.pro/mchus/logpile/web"
)

var (
	version = "dev"
	commit  = "none"
)

func main() {
	holdOnCrash := flag.Bool("hold-on-crash", runtime.GOOS == "windows", "Wait for Enter on crash to keep console open")
	port := flag.Int("port", 8082, "HTTP server port")
	file := flag.String("file", "", "Pre-load archive file")
	showVersion := flag.Bool("version", false, "Show version")
	noBrowser := flag.Bool("no-browser", false, "Don't open browser automatically")
	flag.Parse()

	if *showVersion {
		fmt.Printf("LOGPile %s (commit: %s)\n", version, commit)
		os.Exit(0)
	}

	// Set embedded web files
	server.WebFS = web.FS

	cfg := server.Config{
		Port:        *port,
		PreloadFile: *file,
		AppVersion:  version,
		AppCommit:   commit,
	}

	srv := server.New(cfg)

	url := fmt.Sprintf("http://localhost:%d", *port)
	log.Printf("LOGPile starting on %s", url)
	log.Printf("Registered parsers: %v", parser.ListParsers())

	// Open browser automatically
	if !*noBrowser {
		go func() {
			time.Sleep(500 * time.Millisecond) // Wait for server to start
			openBrowser(url)
		}()
	}

	if err := runServer(srv); err != nil {
		log.Printf("FATAL: %v", err)
		maybeWaitForCrashInput(*holdOnCrash)
		os.Exit(1)
	}
}

func runServer(srv *server.Server) (runErr error) {
	defer func() {
		if recovered := recover(); recovered != nil {
			runErr = fmt.Errorf("panic: %v", recovered)
		}
	}()
	return srv.Run()
}

// openBrowser opens the default browser with the given URL
func openBrowser(url string) {
	var cmd *exec.Cmd

	switch runtime.GOOS {
	case "darwin":
		cmd = exec.Command("open", url)
	case "windows":
		cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
	default: // linux and others
		cmd = exec.Command("xdg-open", url)
	}

	if err := cmd.Start(); err != nil {
		log.Printf("Failed to open browser: %v", err)
	}
}

func maybeWaitForCrashInput(enabled bool) {
	if !enabled || !isInteractiveConsole() {
		return
	}
	fmt.Fprintln(os.Stderr, "\nApplication crashed. Press Enter to close...")
	_, _ = bufio.NewReader(os.Stdin).ReadString('\n')
}

func isInteractiveConsole() bool {
	stdinInfo, err := os.Stdin.Stat()
	if err != nil {
		return false
	}
	stderrInfo, err := os.Stderr.Stat()
	if err != nil {
		return false
	}
	return (stdinInfo.Mode()&os.ModeCharDevice) != 0 && (stderrInfo.Mode()&os.ModeCharDevice) != 0
}
