package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os"
	"strings"
)

func main() {
	// get tikv config info from stdin
	var tikvConfigInfo []byte
	if input, err := os.ReadFile("/dev/stdin"); err != nil {
		panic(err)
	} else {
		tikvConfigInfo = input
	}
	tikvJSON, err := json.MarshalIndent(ParseTikvConfigInfo(tikvConfigInfo), "", "    ")
	if err != nil {
		panic(err)
	}
	if _, err := os.Stdout.Write(tikvJSON); err != nil {
		panic(err)
	}
}

type tikvConfigInfo struct {
	Parameters []struct {
		Name         string `json:"Name"`
		DefaultValue any    `json:"DefaultValue"`
	} `json:"Parameters"`
}

func ParseTikvConfigInfo(input []byte) []Param {
	var configInfo tikvConfigInfo
	decoder := json.NewDecoder(bytes.NewReader(input))
	decoder.UseNumber()
	if err := decoder.Decode(&configInfo); err != nil {
		panic(fmt.Sprintf("Failed to decode Tikv config info: %v", err))
	}

	var params []Param
	for _, param := range configInfo.Parameters {
		ttype := "unknown" // Default type is unknown, as we don't have type information in the input
		if param.DefaultValue != nil {
			switch param.DefaultValue.(type) {
			case string:
				ttype = "string"
			case json.Number:
				if strings.Contains(param.DefaultValue.(json.Number).String(), ".") {
					ttype = "float"
				} else {
					ttype = "int"
				}
			case bool:
				ttype = "bool"
			case []interface{}, map[string]interface{}:
				ttype = "json"
			default:
				panic(fmt.Sprintf("Unknown type for parameter %s: %T", param.Name, param.DefaultValue))
			}
		}
		params = append(params, Param{
			Key:          param.Name,
			Type:         ttype,
			DefaultValue: param.DefaultValue,
		})
	}
	return params
}
