package main

import (
	"context"
	"fmt"
	"log/slog"
	"os"
	"runtime/debug"

	"git.netflux.io/rob/octoplex/internal/domain"
	"git.netflux.io/rob/octoplex/internal/event"
	"git.netflux.io/rob/octoplex/internal/terminal"
	"golang.design/x/clipboard"
)

var (
	// version is the version of the application.
	version string
	// commit is the commit hash of the application.
	commit string
	// date is the date of the build.
	date string
)

func main() {
	if err := run(); err != nil {
		os.Stderr.WriteString("Error: " + err.Error() + "\n")
	}
}

func run() error {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// TODO: logger from config
	fptr, err := os.OpenFile("octoplex.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return fmt.Errorf("open log file: %w", err)
	}
	logger := slog.New(slog.NewTextHandler(fptr, nil))

	bus := event.NewBus(logger)

	var clipboardAvailable bool
	if err = clipboard.Init(); err != nil {
		logger.Warn("Clipboard not available", "err", err)
	} else {
		clipboardAvailable = true
	}

	buildInfo, ok := debug.ReadBuildInfo()
	if !ok {
		return fmt.Errorf("read build info: %w", err)
	}

	ui, err := terminal.StartUI(ctx, terminal.StartParams{
		EventBus: bus,
		Dispatcher: func(cmd event.Command) {
			// TODO: this must call the gRPC client
			logger.Info("Command dispatched", "cmd", cmd)
		},
		ClipboardAvailable: clipboardAvailable,
		ConfigFilePath:     "TODO",
		BuildInfo: domain.BuildInfo{
			GoVersion: buildInfo.GoVersion,
			Version:   version,
			Commit:    commit,
			Date:      date,
		},
		Logger: logger.With("component", "ui"),
	})
	if err != nil {
		return fmt.Errorf("start terminal user interface: %w", err)
	}
	defer ui.Close()

	return nil
}