package main

import (
	"encoding/gob"
	"flag"
	"fmt"
	"log/slog"
	"net/http"
	"os"
	"runtime/debug"

	"brainminder.speedtech.it/internal/database"
	"brainminder.speedtech.it/internal/env"
	"brainminder.speedtech.it/internal/smtp"
	"brainminder.speedtech.it/internal/version"

	"github.com/gorilla/sessions"
	"github.com/lmittmann/tint"
)

func main() {
	gob.Register(map[string]any{})
	logger := slog.New(tint.NewHandler(os.Stdout, &tint.Options{Level: slog.LevelDebug}))

	err := run(logger)
	if err != nil {
		trace := string(debug.Stack())
		logger.Error(err.Error(), "trace", trace)
		os.Exit(1)
	}
}

func run(logger *slog.Logger) error {
	var cfg config

	cfg.publicBaseURL = env.GetString("PUBLIC_BASE_URL", "http://localhost:4445")
	cfg.baseURL = env.GetString("BASE_URL", "http://localhost")
	cfg.httpPort = env.GetInt("HTTP_PORT", 4445)
	cfg.cookie.secretKey = env.GetString("COOKIE_SECRET_KEY", `CHANGE_THIS_COOKIE_KEY`)
	cfg.db.dsn = env.GetString("DB_DSN", "db.sqlite")
	cfg.db.automigrate = env.GetBool("DB_AUTOMIGRATE", true)
	cfg.session.secretKey = env.GetString("SESSION_SECRET_KEY", `CHANGE_THIS_SESSION_KEY`)
	cfg.session.oldSecretKey = env.GetString("SESSION_OLD_SECRET_KEY", "")
	cfg.smtp.host = env.GetString("SMTP_HOST", "example.smtp.host")
	cfg.smtp.port = env.GetInt("SMTP_PORT", 25)
	cfg.smtp.username = env.GetString("SMTP_USERNAME", "example_username")
	cfg.smtp.password = env.GetString("SMTP_PASSWORD", "pa55word")
	cfg.smtp.from = env.GetString("SMTP_FROM", "Example Name <no_reply@example.org>")

	showVersion := flag.Bool("version", false, "display version and exit")

	flag.Parse()

	if *showVersion {
		fmt.Printf("version: %s\n", version.Get())
		return nil
	}

	db, err := database.New(cfg.db.dsn, cfg.db.automigrate)
	if err != nil {
		return err
	}
	defer func(db *database.DB) {
		err := db.Close()
		if err != nil {
			logger.Error("Building category update form buffer after post on create : ", err)
		}
	}(db)

	mailer, err := smtp.NewMailer(cfg.smtp.host, cfg.smtp.port, cfg.smtp.username, cfg.smtp.password, cfg.smtp.from)
	if err != nil {
		return err
	}

	keyPairs := [][]byte{[]byte(cfg.session.secretKey), nil}
	if cfg.session.oldSecretKey != "" {
		keyPairs = append(keyPairs, []byte(cfg.session.oldSecretKey), nil)
	}

	sessionStore := sessions.NewCookieStore(keyPairs...)
	sessionStore.Options = &sessions.Options{
		HttpOnly: true,
		MaxAge:   86400 * 7,
		Path:     "/",
		SameSite: http.SameSiteLaxMode,
		Secure:   true,
	}

	app := &application{
		config:       cfg,
		db:           db,
		logger:       logger,
		mailer:       mailer,
		sessionStore: sessionStore,
	}

	return app.serveHTTP()
}
