// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package golang

import (
	"fmt"
	"strconv"

	"v.io/v23/vdl"
	"v.io/x/ref/lib/vdl/compile"
	"v.io/x/ref/lib/vdl/parse"
)

func constDefGo(data goData, def *compile.ConstDef) string {
	v := def.Value
	return fmt.Sprintf("%s%s %s = %s%s", def.Doc, constOrVar(v.Kind()), def.Name, typedConst(data, v), def.DocSuffix)
}

func constOrVar(k vdl.Kind) string {
	switch k {
	case vdl.Bool, vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Float32, vdl.Float64, vdl.Complex64, vdl.Complex128, vdl.String, vdl.Enum:
		return "const"
	}
	return "var"
}

func isByteList(t *vdl.Type) bool {
	return t.Kind() == vdl.List && t.Elem().Kind() == vdl.Byte
}

func tagValue(data goData, v *vdl.Value) string {
	return typedConst(data, vdl.AnyValue(v))
}

// TODO(bprosnitz): Generate the full tag name e.g. security.Read instead of
// security.Label(1)
//
// TODO(toddw): This doesn't work at all if v.Type() is a native type, or has
// subtypes that are native types.  It's also broken for optional types that
// can't be represented using a composite literal (e.g. optional primitives).
//
// https://github.com/vanadium/issues/issues/213
func typedConst(data goData, v *vdl.Value) string {
	k, t := v.Kind(), v.Type()
	if k == vdl.Optional {
		if elem := v.Elem(); elem != nil {
			return "&" + typedConst(data, elem)
		}
		return "(" + typeGo(data, t) + ")(nil)" // results in (*Foo)(nil)
	}
	valstr := untypedConst(data, v)
	// Enum, TypeObject and Any already include the type in their values.
	// Built-in bool and string are implicitly convertible from literals.
	if k == vdl.Enum || k == vdl.TypeObject || k == vdl.Any || t == vdl.BoolType || t == vdl.StringType {
		return valstr
	}
	// Everything else requires an explicit type.
	typestr := typeGo(data, t)
	// { } are used instead of ( ) for composites
	switch k {
	case vdl.Array, vdl.Struct:
		return typestr + valstr
	case vdl.List, vdl.Set, vdl.Map:
		// Special-case []byte, which we generate as a type conversion from string,
		// and empty variable-length collections, which we generate as a type
		// conversion from nil.
		if !isByteList(t) && !v.IsZero() {
			return typestr + valstr
		}
	}
	return typestr + "(" + valstr + ")"
}

func untypedConst(data goData, v *vdl.Value) string {
	k, t := v.Kind(), v.Type()
	if isByteList(t) {
		if v.IsZero() {
			return "nil"
		}
		return strconv.Quote(string(v.Bytes()))
	}
	switch k {
	case vdl.Any:
		if elem := v.Elem(); elem != nil {
			// We need to generate a Go expression of type *vdl.Value that represents
			// elem.  Since the rest of our logic can already generate the Go code for
			// any value, we just wrap it in vdl.ValueOf to produce the final result.
			//
			// This may seem like a strange roundtrip, but results in less generator
			// and generated code.
			return data.Pkg("v.io/v23/vdl") + "ValueOf(" + typedConst(data, elem) + ")"
		}
		return "(*" + data.Pkg("v.io/v23/vdl") + "Value)(nil)"
	case vdl.Optional:
		if elem := v.Elem(); elem != nil {
			return untypedConst(data, elem)
		}
		return "nil"
	case vdl.TypeObject:
		// We special-case Any and TypeObject, since they cannot be named by the
		// user, and are simple to return statically.
		switch v.TypeObject().Kind() {
		case vdl.Any:
			return data.Pkg("v.io/v23/vdl") + "AnyType"
		case vdl.TypeObject:
			return data.Pkg("v.io/v23/vdl") + "TypeObjectType"
		}
		// We need to generate a Go expression of type *vdl.Type that represents the
		// type.  Since the rest of our logic can already generate the Go code for
		// any value, we just wrap it in vdl.TypeOf to produce the final result.
		//
		// This may seem like a strange roundtrip, but results in less generator
		// and generated code.
		zero := vdl.ZeroValue(v.TypeObject())
		return data.Pkg("v.io/v23/vdl") + "TypeOf(" + typedConst(data, zero) + ")"
	case vdl.Bool:
		return strconv.FormatBool(v.Bool())
	case vdl.Byte:
		return strconv.FormatUint(uint64(v.Byte()), 10)
	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
		return strconv.FormatUint(v.Uint(), 10)
	case vdl.Int16, vdl.Int32, vdl.Int64:
		return strconv.FormatInt(v.Int(), 10)
	case vdl.Float32, vdl.Float64:
		return formatFloat(v.Float(), k)
	case vdl.Complex64, vdl.Complex128:
		switch re, im := real(v.Complex()), imag(v.Complex()); {
		case im > 0:
			return formatFloat(re, k) + "+" + formatFloat(im, k) + "i"
		case im < 0:
			return formatFloat(re, k) + formatFloat(im, k) + "i"
		default:
			return formatFloat(re, k)
		}
	case vdl.String:
		return strconv.Quote(v.RawString())
	case vdl.Enum:
		return typeGo(data, t) + v.EnumLabel()
	case vdl.Array:
		if v.IsZero() && !t.ContainsKind(vdl.WalkInline, vdl.TypeObject, vdl.Union) {
			// We can't rely on the golang zero-value array if t contains inline
			// typeobject or union, since the golang zero-value for these types is
			// different from the vdl zero-value for these types.
			return "{}"
		}
		s := "{"
		for ix := 0; ix < v.Len(); ix++ {
			s += "\n" + untypedConst(data, v.Index(ix)) + ","
		}
		return s + "\n}"
	case vdl.List:
		if v.IsZero() {
			return "nil"
		}
		s := "{"
		for ix := 0; ix < v.Len(); ix++ {
			s += "\n" + untypedConst(data, v.Index(ix)) + ","
		}
		return s + "\n}"
	case vdl.Set, vdl.Map:
		if v.IsZero() {
			return "nil"
		}
		s := "{"
		for _, key := range vdl.SortValuesAsString(v.Keys()) {
			s += "\n" + subConst(data, key)
			if k == vdl.Set {
				s += ": struct{}{},"
			} else {
				s += ": " + untypedConst(data, v.MapIndex(key)) + ","
			}
		}
		return s + "\n}"
	case vdl.Struct:
		s := "{"
		hasFields := false
		for ix := 0; ix < t.NumField(); ix++ {
			vf := v.StructField(ix)
			if !vf.IsZero() || vf.Type().ContainsKind(vdl.WalkInline, vdl.TypeObject, vdl.Union) {
				// We can't rely on the golang zero-value for this field, even if it's a
				// vdl zero value, if the field contains inline typeobject or union,
				// since the golang zero-value for these types is different from the vdl
				// zero-value for these types.
				s += "\n" + t.Field(ix).Name + ": " + subConst(data, vf) + ","
				hasFields = true
			}
		}
		if hasFields {
			s += "\n"
		}
		return s + "}"
	case vdl.Union:
		ix, field := v.UnionField()
		return typeGo(data, t) + t.Field(ix).Name + "{" + typedConst(data, field) + "}"
	default:
		data.Env.Errorf(data.File, parse.Pos{}, "%v untypedConst not implemented for %v %v", t, k)
		return "INVALID"
	}
}

// subConst deals with a quirk regarding Go composite literals.  Go allows us to
// elide the type from composite literal Y when the type is implied; basically
// when Y is contained in another composite literal X.  However it requires the
// type for Y when X is a struct, and when X is a map and Y is the key.  As such
// subConst is called for map keys and struct fields.
func subConst(data goData, v *vdl.Value) string {
	switch v.Kind() {
	case vdl.Array, vdl.List, vdl.Set, vdl.Map, vdl.Struct, vdl.Optional:
		return typedConst(data, v)
	}
	return untypedConst(data, v)
}

func formatFloat(x float64, kind vdl.Kind) string {
	var bitSize int
	switch kind {
	case vdl.Float32, vdl.Complex64:
		bitSize = 32
	case vdl.Float64, vdl.Complex128:
		bitSize = 64
	default:
		panic(fmt.Errorf("vdl: formatFloat unhandled kind: %v", kind))
	}
	return strconv.FormatFloat(x, 'g', -1, bitSize)
}
