//go:build ignore

package main

import (
	"bytes"
	"go/format"
	"os"
	"path/filepath"
	"sort"
	"text/template"

	"gopkg.in/yaml.v3"
)

type Palette struct {
	Base00 string `yaml:"base00"`
	Base01 string `yaml:"base01"`
	Base02 string `yaml:"base02"`
	Base03 string `yaml:"base03"`
	Base04 string `yaml:"base04"`
	Base05 string `yaml:"base05"`
	Base06 string `yaml:"base06"`
	Base07 string `yaml:"base07"`
	Base08 string `yaml:"base08"`
	Base09 string `yaml:"base09"`
	Base0A string `yaml:"base0A"`
	Base0B string `yaml:"base0B"`
	Base0C string `yaml:"base0C"`
	Base0D string `yaml:"base0D"`
	Base0E string `yaml:"base0E"`
	Base0F string `yaml:"base0F"`
}

type Scheme struct {
	Name     string
	Filename string
	Palette
}

const DEFAULTS_TEMPLATE = `// Code generated by gen.go; DO NOT EDIT.
package colormaps

import (
	"github.com/cfoust/cy/pkg/janet"
	"github.com/cfoust/cy/pkg/style"

	"github.com/charmbracelet/lipgloss"
)

var Schemes []Scheme

func init() {
	Schemes = []Scheme{
		{{- range . }}
		{
			ID: janet.Keyword("{{ .Filename }}"),
			Name: "{{ .Name }}",
			Map: style.NewColorMap(map[lipgloss.Color]lipgloss.Color{
				// normal
				lipgloss.Color("0"): lipgloss.Color("#{{ .Palette.Base00 }}"),
				lipgloss.Color("1"): lipgloss.Color("#{{ .Palette.Base08 }}"),
				lipgloss.Color("2"): lipgloss.Color("#{{ .Palette.Base0B }}"),
				lipgloss.Color("3"): lipgloss.Color("#{{ .Palette.Base0A }}"),
				lipgloss.Color("4"): lipgloss.Color("#{{ .Palette.Base0D }}"),
				lipgloss.Color("5"): lipgloss.Color("#{{ .Palette.Base0E }}"),
				lipgloss.Color("6"): lipgloss.Color("#{{ .Palette.Base0C }}"),
				lipgloss.Color("7"): lipgloss.Color("#{{ .Palette.Base05 }}"),

				// bright
				lipgloss.Color("8"): lipgloss.Color("#{{ .Palette.Base03 }}"),
				lipgloss.Color("9"): lipgloss.Color("#{{ .Palette.Base09 }}"),
				lipgloss.Color("10"): lipgloss.Color("#{{ .Palette.Base01 }}"),
				lipgloss.Color("11"): lipgloss.Color("#{{ .Palette.Base02 }}"),
				lipgloss.Color("12"): lipgloss.Color("#{{ .Palette.Base04 }}"),
				lipgloss.Color("13"): lipgloss.Color("#{{ .Palette.Base06 }}"),
				lipgloss.Color("14"): lipgloss.Color("#{{ .Palette.Base0F }}"),
				lipgloss.Color("15"): lipgloss.Color("#{{ .Palette.Base07 }}"),
			}),
		},
		{{- end }}
	}

}

`

func main() {
	// Get filenames for all files in schemes dir
	files, err := filepath.Glob("schemes/*.yaml")
	if err != nil {
		panic(err)
	}

	schemes := []Scheme{}
	for _, file := range files {
		bytes, err := os.ReadFile(file)
		if err != nil {
			panic(err)
		}

		scheme := Scheme{}
		err = yaml.Unmarshal([]byte(bytes), &scheme)
		if err != nil {
			panic(err)
		}

		// remove extension from file
		scheme.Filename = filepath.Base(file[:len(file)-5])

		schemes = append(schemes, scheme)
	}

	sort.SliceStable(schemes, func(i, j int) bool {
		return schemes[i].Filename < schemes[j].Filename
	})

	tmpl, err := template.
		New("defaults").
		Parse(DEFAULTS_TEMPLATE)
	if err != nil {
		panic(err)
	}

	output := bytes.Buffer{}
	err = tmpl.Execute(&output, schemes)
	if err != nil {
		panic(err)
	}

	formatted, err := format.Source(output.Bytes())
	if err != nil {
		panic(err)
	}

	f, err := os.Create("schemes_gen.go")
	if err != nil {
		panic(err)
	}
	f.Write(formatted)
}
