//+build ignore

// gen_soundIDs.go generates the enumeration of sound IDs.
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"sort"
)

const (
	protocolURL = "https://pokechu22.github.io/Burger/1.16.5.json"
)

type sound struct {
	ID   int64
	Name string
}

//go:generate go run $GOFILE
func main() {
	sounds, err := downloadSoundInfo()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}

	f, err := os.Create("soundid.go")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}
	defer f.Close()

	fmt.Fprintln(f, "// Code generated by gen_soundIDs.go. DO NOT EDIT.")
	fmt.Fprintln(f)
	fmt.Fprintln(f, "package soundid")
	fmt.Fprintln(f)

	fmt.Fprintln(f, "// SoundID represents a sound ID used in the minecraft protocol.")
	fmt.Fprintln(f, "type SoundID int32")
	fmt.Fprintln(f)
	fmt.Fprintln(f, "// SoundNames - map of ids to names for sounds.")

	fmt.Fprintln(f, "var SoundNames map[SoundID]string = map[SoundID]string{")
	for _, v := range sounds {
		fmt.Fprintf(f, `    %d: "%s",`, v.ID, v.Name)
		fmt.Fprintln(f)
	}
	fmt.Fprintln(f, "}")
	fmt.Fprintln(f)

	fmt.Fprintln(f, "// GetSoundNameByID helper method")
	fmt.Fprintln(f, "func GetSoundNameByID(id SoundID) (string,bool) {")
	fmt.Fprintln(f, "    name, ok := SoundNames[id]")
	fmt.Fprintln(f, "    return name, ok")
	fmt.Fprintln(f, "}")
}

func downloadSoundInfo() ([]sound, error) {
	resp, err := http.Get(protocolURL)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	x := []map[string]interface{}{}

	// if err := json.Unmarshal([]byte(data), &x); err != nil {
	if err := json.NewDecoder(resp.Body).Decode(&x); err != nil {
		return nil, err
	}

	out := []sound{}
	for i := range x {
		if sounds, ok := x[i]["sounds"]; ok {
			// fmt.Fprintf("sounds: %#v\n", sounds)
			for _, value := range sounds.(map[string]interface{}) {
				// fmt.Fprintf("%d: %s\n", int64(value.(map[string]interface{})["id"].(float64)), value.(map[string]interface{})["name"])
				out = append(out, sound{ID: int64(value.(map[string]interface{})["id"].(float64)), Name: value.(map[string]interface{})["name"].(string)})
			}
		} else {
			// fmt.Fprintf("NO SOUNDS FOUND IN DATA!")
			return nil, fmt.Errorf("No sounds found in data from %s", protocolURL)
		}
	}

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

	return out, nil
}
