package datatype

import (
	"fmt"

	"github.com/emicklei/proto"

	"github.com/ignite/cli/v29/ignite/pkg/multiformatname"
	"github.com/ignite/cli/v29/ignite/pkg/protoanalysis/protoutil"
)

// DataCustom is a custom data type definition.
var DataCustom = DataType{
	Name:                    Custom,
	DataType:                func(datatype string) string { return fmt.Sprintf("*%s", datatype) },
	CollectionsKeyValueName: func(string) string { return collectionValueComment },
	DefaultTestValue:        "{}",
	ValueLoop:               "nil",
	ProtoType: func(datatype, name string, index int) string {
		return fmt.Sprintf("%s %s = %d", datatype, name, index)
	},
	GenesisArgs: func(name multiformatname.Name, _ int) string {
		return fmt.Sprintf("%s: new(types.%s),\n", name.UpperCamel, name.UpperCamel)
	},
	CLIArgs: func(name multiformatname.Name, datatype, prefix string, argIndex int) string {
		return fmt.Sprintf(`%[1]v%[2]v := new(types.%[3]v)
					err = json.Unmarshal([]byte(args[%[4]v]), %[1]v%[2]v)
    				if err != nil {
                		return err
            		}`, prefix, name.UpperCamel, datatype, argIndex)
	},
	ToProtoField: func(datatype, name string, index int) *proto.NormalField {
		return protoutil.NewField(name, datatype, index)
	},
	GoCLIImports: []GoImport{{Name: "encoding/json"}},
	NonIndex:     true,
}

// DataCustomSlice is a custom array data type definition.
var DataCustomSlice = DataType{
	Name:                    CustomSlice,
	DataType:                func(datatype string) string { return fmt.Sprintf("[]*%s", datatype) },
	CollectionsKeyValueName: func(string) string { return collectionValueComment },
	DefaultTestValue:        "[]",
	ValueLoop:               "nil",
	ProtoType: func(datatype, name string, index int) string {
		return fmt.Sprintf("repeated %s %s = %d", datatype, name, index)
	},
	GenesisArgs: func(name multiformatname.Name, _ int) string {
		return fmt.Sprintf("%s: []*types.%s{},\n", name.UpperCamel, name.UpperCamel)
	},
	CLIArgs: func(name multiformatname.Name, datatype, prefix string, argIndex int) string {
		return fmt.Sprintf(`var %[1]v%[2]v []*types.%[3]v
					err = json.Unmarshal([]byte(args[%[4]v]), &%[1]v%[2]v)
    				if err != nil {
                		return err
            		}`, prefix, name.UpperCamel, datatype, argIndex)
	},
	ToProtoField: func(datatype, name string, index int) *proto.NormalField {
		return protoutil.NewField(name, datatype, index, protoutil.Repeated())
	},
	GoCLIImports: []GoImport{{Name: "encoding/json"}},
	NonIndex:     true,
}
