//go:build ignore

package main

import (
	"bytes"
	_ "embed"
	"encoding/json"
	"fmt"
	"go/format"
	"log"
	"os"
	"sort"
)

//go:embed iso3166.json
var iso3166JSON []byte

func main() {
	if len(os.Args) < 2 {
		log.Fatalln("requires [target-file] argument")

		return
	}
	if err := generate(os.Args[len(os.Args)-1]); err != nil {
		log.Fatalln("cannot generate:", err)

		return
	}
}

// source data for iso3166 countries,
// credits: https://github.com/mrz1836/go-countries/blob/master/data/iso_3166.go
func generate(targetFile string) error {
	out, err := os.Create(targetFile)
	if err != nil {
		return err
	}
	log.Printf("generating %s", targetFile)

	const roughAllocs = 300

	type c struct {
		Name      string `json:"name"`
		ISOAlpha3 string `json:"alpha-3" `
		ISOAlpha2 string `json:"alpha-2"`
		Code      string `json:"country-code"`
	}
	ctries := make([]c, 0, roughAllocs)
	buf := new(bytes.Buffer)

	if err = json.Unmarshal(iso3166JSON, &ctries); err != nil {
		return err
	}

	fmt.Fprint(buf, `// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

// Code generated by gen.go; DO NOT EDIT.

package countries
`)

	index3 := make(map[string]c, len(ctries))
	index2 := make(map[string]c, len(ctries))
	for _, country := range ctries {
		index3[country.ISOAlpha3] = country
		index2[country.ISOAlpha2] = country
	}

	countries3 := make([]c, 0, len(index3))
	for _, country := range index3 {
		countries3 = append(countries3, country)
	}
	sort.Slice(countries3, func(i, j int) bool {
		return countries3[i].ISOAlpha3 < countries3[j].ISOAlpha3
	})

	countries2 := make([]c, 0, len(index2))
	for _, country := range index2 {
		countries2 = append(countries2, country)
	}
	sort.Slice(countries2, func(i, j int) bool {
		return countries2[i].ISOAlpha2 < countries2[j].ISOAlpha2
	})

	fmt.Fprintln(buf, "// CountriesISO3 indexes ISO3166 countries by their alpha-3 code.")
	fmt.Fprintln(buf, "	var CountriesISO3 = map[string]Country{")
	for _, country := range countries3 {
		fmt.Fprintf(buf, "	%q: {Name:%q,ISOAlpha3:%q,ISOAlpha2:%q,Code:%q},\n",
			country.ISOAlpha3,
			country.Name, country.ISOAlpha3, country.ISOAlpha2, country.Code,
		)
	}
	fmt.Fprintln(buf, "	}")
	fmt.Fprintln(buf)

	fmt.Fprintln(buf, "// CountriesISO2 indexes ISO3166 countries by their alpha-2 code.")
	fmt.Fprintln(buf, "	var CountriesISO2 = map[string]Country{")
	for _, country := range countries2 {
		fmt.Fprintf(buf, "	%q: {Name:%q,ISOAlpha3:%q,ISOAlpha2:%q,Code:%q},\n",
			country.ISOAlpha2,
			country.Name, country.ISOAlpha3, country.ISOAlpha2, country.Code,
		)
	}
	fmt.Fprintln(buf, "	}")
	formatted, err := format.Source(buf.Bytes())
	if err != nil {
		_, _ = out.Write(buf.Bytes())
		return fmt.Errorf("format: %w", err)
	}

	_, err = out.Write(formatted)

	return err
}
