// Copyright (c) 2024 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//go:build ignore

package main

import (
	"cmp"
	"fmt"
	"os"
	"slices"
	"strings"

	"go.mau.fi/util/exerrors"
	"go.mau.fi/util/unicodeurls"
)

type Confusable struct {
	From rune
	To   string
}

func loadConfusables() []Confusable {
	return unicodeurls.ReadDataFileList(unicodeurls.Confusables, func(line string) (Confusable, bool) {
		parts := strings.Split(line, ";")
		if len(parts) < 3 {
			return Confusable{}, false
		}
		fromStr := unicodeurls.ParseHex(strings.Split(strings.TrimSpace(parts[0]), " "))
		fromRunes := []rune(fromStr)
		if len(fromRunes) != 1 {
			panic(fmt.Errorf("unexpected source rune %s", strings.TrimSpace(parts[0])))
		}
		return Confusable{
			From: fromRunes[0],
			To:   unicodeurls.ParseHex(strings.Split(strings.TrimSpace(parts[1]), " ")),
		}, true
	})
}

func main() {
	confusables := loadConfusables()
	slices.SortFunc(confusables, func(a, b Confusable) int {
		return cmp.Compare(a.From, b.From)
	})
	file := exerrors.Must(os.OpenFile("confusables.go", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644))
	exerrors.Must(file.WriteString(`// Code generated by go generate; DO NOT EDIT.

package confusable

func GetReplacement(input rune) string {
	switch input {
`))
	for _, confusable := range confusables {
		exerrors.Must(fmt.Fprintf(file, "\tcase %d:\n\t\treturn %q\n", confusable.From, confusable.To))
	}
	exerrors.Must(file.WriteString(`
	default:
		return ""
	}
}
`))
	exerrors.PanicIfNotNil(file.Close())
}
