//go:build ignore

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"regexp"
	"strings"
	"text/template"
	"time"
)

const Directory = "/usr/share/dict"

var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9 ]+`)

var dictionaryTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// {{ .Timestamp }}
// using data from
// {{ .Path }}
package dictionary

import (
	"gitea.elara.ws/Hazel/go-words/internal"
)

var {{ .VarName }} = internal.Dictionary{
{{- range .Words }}
	{{ printf "%q" . }},
{{- end }}
}
`))

type dictionaryTemplateData struct {
	Timestamp time.Time
	Path      string
	Words     []string
	VarName   string
}

var exportTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// {{ .Timestamp }}
// It exports the Dictionaries for easy use

package words

import (
	"gitea.elara.ws/Hazel/go-words/internal/dictionary"
)

//go:generate go run internal/gen.go

{{range $VarName := .VarNames }}
var {{ $VarName }} = dictionary.{{ $VarName }}
{{- end }}
`))

type exportTemplateData struct {
	Timestamp time.Time
	VarNames  []string
}

func generateFile(name string) string {
	fmt.Println("generating file for dictionary " + name)

	lowerName := strings.ToLower(name)

	words := []string{}
	Path := Directory + "/" + lowerName

	file, err := os.Open(Path)
	if err != nil {
		die(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		w := strings.TrimSpace(scanner.Text())
		if regexp.MustCompile(`^[a-zA-Z0-9]*$`).MatchString(w) {
			words = append(words, w)
		}

	}

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

	f, err := os.Create("internal/dictionary/" + lowerName + ".go")
	die(err)
	defer f.Close()

	varName := nonAlphanumericRegex.ReplaceAllString(strings.Title(name), "")
	dictionaryTemplate.Execute(f, dictionaryTemplateData{
		Timestamp: time.Now(),
		Path:      Path,
		Words:     words,
		VarName:   varName,
	})

	return varName
}

func main() {
	fmt.Println("Generate")

	entries, err := os.ReadDir(Directory)
	if err != nil {
		die(err)
	}

	varNames := make([]string, 0)
	for _, e := range entries {
		if !strings.Contains(e.Name(), ".") {
			varNames = append(varNames, generateFile(e.Name()))
		}
	}

	f, err := os.Create("main.go")
	die(err)
	defer f.Close()
	exportTemplate.Execute(f, exportTemplateData{
		Timestamp: time.Now(),
		VarNames:  varNames,
	})
}

func die(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
