// 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 java

import (
	"fmt"
	"strconv"
	"strings"

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

const javaMaxStringLen = 2 << 16 // 64k

// javaConstVal returns the value string for the provided constant value.
func javaConstVal(v *vdl.Value, env *compile.Env) (ret string) {
	if v == nil {
		return "null"
	}
	if v.IsZero() {
		return javaZeroValue(v.Type(), env)
	}

	ret = javaVal(v, env)
	switch v.Type().Kind() {
	case vdl.Complex64, vdl.Complex128, vdl.Enum, vdl.Union, vdl.Uint16, vdl.Uint32, vdl.Uint64:
		return
	}
	if def := env.FindTypeDef(v.Type()); def != nil && def.File != compile.BuiltInFile { // User-defined type.
		ret = fmt.Sprintf("new %s(%s)", javaType(v.Type(), false, env), ret)
	}
	return
}

// javaVal returns the value string for the provided Value.
func javaVal(v *vdl.Value, env *compile.Env) string {
	const longSuffix = "L"
	const floatSuffix = "f"

	if v.Kind() == vdl.Array || (v.Kind() == vdl.List && v.Type().Elem().Kind() == vdl.Byte && v.Type().Name() == "") {
		ret := fmt.Sprintf("new %s[] {", javaType(v.Type().Elem(), false, env))
		for i := 0; i < v.Len(); i++ {
			if i > 0 {
				ret = ret + ", "
			}
			ret = ret + javaConstVal(v.Index(i), env)
		}
		return ret + "}"
	}

	switch v.Kind() {
	case vdl.Bool:
		if v.Bool() {
			return "true"
		} else {
			return "false"
		}
	case vdl.Byte:
		return "(byte)0x" + strconv.FormatUint(uint64(v.Byte()), 16)
	case vdl.Uint16:
		return fmt.Sprintf("new %s((short) %s)", javaType(v.Type(), true, env), strconv.FormatUint(v.Uint(), 10))
	case vdl.Int16:
		return "(short)" + strconv.FormatInt(v.Int(), 10)
	case vdl.Uint32:
		return fmt.Sprintf("new %s((int) %s)", javaType(v.Type(), true, env), strconv.FormatUint(v.Uint(), 10)+longSuffix)
	case vdl.Int32:
		return strconv.FormatInt(v.Int(), 10)
	case vdl.Uint64:
		return fmt.Sprintf("new %s(%s)", javaType(v.Type(), true, env), strconv.FormatInt(int64(v.Uint()), 10)+longSuffix)
	case vdl.Int64:
		return strconv.FormatInt(v.Int(), 10) + longSuffix
	case vdl.Float32, vdl.Float64:
		c := strconv.FormatFloat(v.Float(), 'g', -1, bitlen(v.Kind()))
		if strings.Index(c, ".") == -1 {
			c += ".0"
		}
		if v.Kind() == vdl.Float32 {
			return c + floatSuffix
		}
		return c
	case vdl.Complex64, vdl.Complex128:
		r := strconv.FormatFloat(real(v.Complex()), 'g', -1, bitlen(v.Kind()))
		i := strconv.FormatFloat(imag(v.Complex()), 'g', -1, bitlen(v.Kind()))
		if v.Kind() == vdl.Complex64 {
			r = r + "f"
			i = i + "f"
		}
		return fmt.Sprintf("new %s(%s, %s)", javaType(v.Type(), true, env), r, i)
	case vdl.String:
		in := v.RawString()
		if len(in) < javaMaxStringLen {
			return strconv.Quote(in)
		}

		// Java is unable to handle constant strings larger than 64k so split them into multiple strings.
		out := "String.join(\"\", new java.util.ArrayList<CharSequence>("
		for len(in) > javaMaxStringLen {
			out += strconv.Quote(in[:javaMaxStringLen]) + ","
			in = in[javaMaxStringLen:]
		}
		return out + strconv.Quote(in) + "))"
	case vdl.Any:
		if v.Elem() == nil {
			return fmt.Sprintf("new %s()", javaType(v.Type(), false, env))
		}
		elemReflectTypeStr := javaReflectType(v.Elem().Type(), env)
		elemStr := javaConstVal(v.Elem(), env)
		return fmt.Sprintf("new %s(%s, %s)", javaType(v.Type(), false, env), elemReflectTypeStr, elemStr)
	case vdl.Enum:
		return fmt.Sprintf("%s.%s", javaType(v.Type(), false, env), v.EnumLabel())
	case vdl.List:
		elemTypeStr := javaType(v.Type().Elem(), true, env)
		ret := fmt.Sprintf("new com.google.common.collect.ImmutableList.Builder<%s>()", elemTypeStr)
		for i := 0; i < v.Len(); i++ {
			ret = fmt.Sprintf("%s.add(%s)", ret, javaConstVal(v.Index(i), env))
		}
		return ret + ".build()"
	case vdl.Map:
		keyTypeStr := javaType(v.Type().Key(), true, env)
		elemTypeStr := javaType(v.Type().Elem(), true, env)
		ret := fmt.Sprintf("new com.google.common.collect.ImmutableMap.Builder<%s, %s>()", keyTypeStr, elemTypeStr)
		for _, key := range vdl.SortValuesAsString(v.Keys()) {
			keyStr := javaConstVal(key, env)
			elemStr := javaConstVal(v.MapIndex(key), env)
			ret = fmt.Sprintf("%s.put(%s, %s)", ret, keyStr, elemStr)
		}
		return ret + ".build()"
	case vdl.Union:
		index, value := v.UnionField()
		name := v.Type().Field(index).Name
		elemStr := javaConstVal(value, env)
		return fmt.Sprintf("new %s.%s(%s)", javaType(v.Type(), false, env), name, elemStr)
	case vdl.Set:
		keyTypeStr := javaType(v.Type().Key(), true, env)
		ret := fmt.Sprintf("new com.google.common.collect.ImmutableSet.Builder<%s>()", keyTypeStr)
		for _, key := range vdl.SortValuesAsString(v.Keys()) {
			ret = fmt.Sprintf("%s.add(%s)", ret, javaConstVal(key, env))
		}
		return ret + ".build()"
	case vdl.Struct:
		var ret string
		for i := 0; i < v.Type().NumField(); i++ {
			if i > 0 {
				ret = ret + ", "
			}
			ret = ret + javaConstVal(v.StructField(i), env)
		}
		return ret
	case vdl.TypeObject:
		return fmt.Sprintf("new %s(%s)", javaType(v.Type(), false, env), javaReflectType(v.TypeObject(), env))
	case vdl.Optional:
		if v.Elem() != nil {
			return fmt.Sprintf("io.v.v23.vdl.VdlOptional.of(%s)", javaConstVal(v.Elem(), env))
		} else {
			return fmt.Sprintf("new %s(%s)", javaType(v.Type(), false, env), javaReflectType(v.Type(), env))
		}
	}
	panic(fmt.Errorf("vdl: javaVal unhandled type %v %v", v.Kind(), v.Type()))
}

// javaZeroValue returns the zero value string for the provided VDL value.
// We assume that default constructor of user-defined types returns a zero value.
func javaZeroValue(t *vdl.Type, env *compile.Env) string {
	if _, ok := javaNativeType(t, env); ok {
		return "null"
	}

	// First process user-defined types.
	switch t.Kind() {
	case vdl.Enum:
		return fmt.Sprintf("%s.%s", javaType(t, false, env), t.EnumLabel(0))
	case vdl.Union:
		return fmt.Sprintf("new %s.%s()", javaType(t, false, env), t.Field(0).Name)
	}
	if def := env.FindTypeDef(t); def != nil && def.File != compile.BuiltInFile {
		return fmt.Sprintf("new %s()", javaType(t, false, env))
	}

	// Arrays, enums, structs and unions can be user-defined only.
	if t.Kind() == vdl.List && t.Elem().Kind() == vdl.Byte {
		return fmt.Sprintf("new %s[]{}", javaType(t.Elem(), false, env))
	}
	switch t.Kind() {
	case vdl.Bool:
		return "false"
	case vdl.Byte:
		return "(byte) 0"
	case vdl.Int16:
		return "(short) 0"
	case vdl.Int32:
		return "0"
	case vdl.Int64:
		return "0L"
	case vdl.Float32:
		return "0.0f"
	case vdl.Float64:
		return "0.0"
	case vdl.Any, vdl.Complex64, vdl.Complex128, vdl.TypeObject, vdl.Uint16, vdl.Uint32, vdl.Uint64:
		return fmt.Sprintf("new %s()", javaType(t, false, env))
	case vdl.String:
		return "\"\""
	case vdl.List:
		return fmt.Sprintf("new java.util.ArrayList<%s>()", javaType(t.Elem(), true, env))
	case vdl.Map:
		keyTypeStr := javaType(t.Key(), true, env)
		elemTypeStr := javaType(t.Elem(), true, env)
		return fmt.Sprintf("new java.util.HashMap<%s, %s>()", keyTypeStr, elemTypeStr)
	case vdl.Set:
		return fmt.Sprintf("new java.util.HashSet<%s>()", javaType(t.Key(), true, env))
	case vdl.Optional:
		return fmt.Sprintf("new %s(%s)", javaType(t, false, env), javaReflectType(t, env))
	}
	panic(fmt.Errorf("vdl: javaZeroValue unhandled type %v", t))
}
