// 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.Enum, vdl.Union, vdl.Int8, 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(v.Uint(), 16)
	case vdl.Int8:
		return fmt.Sprintf("new %s((byte) %s)", javaType(v.Type(), true, env), strconv.FormatInt(v.Int(), 10))
	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:
		// Note: this is formatting the number as an int because Java will error on unsigned contants that use the
		// full 64-bits.
		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.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\n.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\n.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\n.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.TypeObject, vdl.Int8, 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))
}
