package main

import (
	"autobrew/alchemy"
	"autobrew/parser"
	"autobrew/recipe"
	"autobrew/utils"
	"embed"
	"fmt"
	"image"
	"os"
	"slices"
	"strings"

	config "github.com/ThomasObenaus/go-conf"

	"github.com/bendahl/uinput"
)

//go:embed recipes.txt
var s embed.FS

type Config struct {
	X      int    `cfg:"{'name':'x','desc':'x offset','default':0}"`
	Y      int    `cfg:"{'name':'y','desc':'y offset','default':0}"`
	Width  int    `cfg:"{'name':'width','desc':'search area width','default':2560}"`
	Height int    `cfg:"{'name':'height','desc':'search area height','default':1440}"`
	Save   bool   `cfg:"{'name':'save','desc':'save ocr image as output.png','default':false}"`
	List   bool   `cfg:"{'name':'list','desc':'list all recipes','default':false,'short':'l'}"`
	Recipe string `cfg:"{'name':'recipe','desc':'specific recipe to make','short':'r','default':''}"`
	Amount int    `cfg:"{'name':'amount','desc':'amount to make','default':1,'short':'n'}"`
}

var cfg = Config{
	X:      2560,
	Y:      0,
	Width:  1280,
	Height: 1440,
	Save:   false,
	List:   false,
	Amount: 1,
}

func main() {

	prefixForEnvironmentVariables := "AUTOBREW"
	nameOfTheConfig := "AUTOBREW"
	provider, err := config.NewConfigProvider(
		&cfg,
		nameOfTheConfig,
		prefixForEnvironmentVariables,
	)
	if err != nil {
		panic(err)
	}

	if len(os.Args) >= 1 {
		err = provider.ReadConfig(os.Args[1:])
		if err != nil {
			fmt.Printf("Error: %s\n", err.Error())
			fmt.Println("Usage:")
			fmt.Print(provider.Usage())
			os.Exit(1)
		}
	}

	recipes_src, err := s.Open("recipes.txt")
	utils.Check(err)
	defer recipes_src.Close()

	var book map[string][]recipe.Step = parser.FromText(recipes_src)

	if cfg.List {
		list := make([]string, 0)
		for v := range book {
			list = append(list, v)
		}
		slices.Sort(list)
		fmt.Println(strings.Join(list, "\n"))
		os.Exit(0)
	} else {
		if len(cfg.Recipe) == 0 {
			fmt.Println("Recipe is required")
			fmt.Print(provider.Usage())
			os.Exit(1)
		}
	}

	if _, ok := book[cfg.Recipe]; !ok {
		panic(fmt.Errorf("Recipe %s not found\n", cfg.Recipe))
	}

	mouse, err := uinput.CreateMouse("/dev/uinput", []byte("brewer-mouse"))
	utils.Check(err)
	defer mouse.Close()

	keyboard, err := uinput.CreateKeyboard("/dev/uinput", []byte("brewer-keyboard"))
	utils.Check(err)
	defer keyboard.Close()

	alchemy := alchemy.NewAlchemy(mouse, keyboard, image.Rect(cfg.X, cfg.Y, cfg.Width+cfg.X, cfg.Height+cfg.Y), cfg.Save)

	alchemy.Brew(book, cfg.Recipe, cfg.Amount)
}
