// Package javascript implements Javascript code generation from compiled VDL packages.
package javascript

// Generates the javascript source code for vdl files.  The generated output in javascript
// differs from most other languages, since we don't generate stubs. Instead generate an
// object that contains the parsed VDL structures that will be used by the Javascript code
// to valid servers.

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"path/filepath"
	"strconv"
	"strings"
	"text/template"

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

type data struct {
	Pkg            *compile.Package
	Env            *compile.Env
	GenerateImport func(string) string
	UserImports    jsImports
	PathToCoreJS   string
	TypeNames      typeNames
}

// Generate takes a populated compile.Package and produces a byte slice
// containing the generated Javascript code.
func Generate(pkg *compile.Package, env *compile.Env, genImport func(string) string, pathToCoreJS string) []byte {
	data := data{
		Pkg:            pkg,
		Env:            env,
		GenerateImport: genImport,
		UserImports:    jsImportsForFiles(pkg.Files...),
		TypeNames:      newTypeNames(pkg),
		PathToCoreJS:   pathToCoreJS,
	}
	var buf bytes.Buffer
	if err := javascriptTemplate.Execute(&buf, data); err != nil {
		// We shouldn't see an error; it means our template is buggy.
		panic(fmt.Errorf("vdl: couldn't execute template: %v", err))
	}
	return buf.Bytes()
}

var javascriptTemplate *template.Template

func bitlen(kind vdl.Kind) int {
	switch kind {
	case vdl.Float32, vdl.Complex64:
		return 32
	case vdl.Float64, vdl.Complex128:
		return 64
	}
	panic(fmt.Errorf("vdl: bitLen unhandled kind %v", kind))
}

func genMethodTags(names typeNames, method *compile.Method) string {
	tags := method.Tags
	result := "["
	for _, tag := range tags {
		result += typedConst(names, tag) + ", "
	}
	result += "]"
	return result
}

// Format the given int64 into a JS BigInt.
func formatUint64BigInt(v uint64) string {
	buffer := make([]byte, 8)
	binary.BigEndian.PutUint64(buffer, v)
	sign := "0"
	if v > 0 {
		sign = "1"
	}
	return fmt.Sprintf("new vdl.BigInt(%s, %s)", sign, formatByteBuffer(buffer))
}

// Format the given int64 into a JS BigInt.
func formatInt64BigInt(v int64) string {
	buffer := make([]byte, 8)
	var sign int64 = 0
	if v > 0 {
		sign = 1
	} else if v < 0 {
		sign = -1
	}
	binary.BigEndian.PutUint64(buffer, uint64(v*sign)) // Adjust value by sign.

	return fmt.Sprintf("new vdl.BigInt(%d, %s)", sign, formatByteBuffer(buffer))
}

// Given a buffer of bytes, create the JS Uint8Array that corresponds to it (to be used with BigInt).
func formatByteBuffer(buffer []byte) string {
	buf := bytes.TrimLeft(buffer, "\x00") // trim leading zeros
	str := "new Uint8Array(["
	for i, b := range buf {
		if i > 0 {
			str += ", "
		}
		str += fmt.Sprintf("%#x", b)
	}
	str += "])"
	return str
}

// untypedConst generates a javascript string representing a constant that is
// not wrapped with type information.
func untypedConst(names typeNames, v *vdl.Value) string {
	switch v.Kind() {
	case vdl.Bool:
		if v.Bool() {
			return "true"
		} else {
			return "false"
		}
	case vdl.Byte:
		return strconv.FormatUint(uint64(v.Byte()), 10)
	case vdl.Uint16, vdl.Uint32:
		return strconv.FormatUint(v.Uint(), 10)
	case vdl.Int16, vdl.Int32:
		return strconv.FormatInt(v.Int(), 10)
	case vdl.Uint64:
		return formatUint64BigInt(v.Uint())
	case vdl.Int64:
		return formatInt64BigInt(v.Int())
	case vdl.Float32, vdl.Float64:
		return strconv.FormatFloat(v.Float(), 'g', -1, bitlen(v.Kind()))
	case vdl.String:
		return strconv.Quote(v.RawString())
	case vdl.Any:
		if v.Elem() != nil {
			return typedConst(names, v.Elem())
		}
		return "null"
	case vdl.Optional:
		if v.Elem() != nil {
			return untypedConst(names, v.Elem())
		}
		return "null"
	case vdl.Complex64, vdl.Complex128:
		return fmt.Sprintf("new vdl.Complex(%f, %f)", real(v.Complex()), imag(v.Complex()))
	case vdl.Enum:
		return fmt.Sprintf("'%s'", v.EnumLabel())
	case vdl.Array, vdl.List:
		result := "["
		for ix := 0; ix < v.Len(); ix++ {
			val := untypedConst(names, v.Index(ix))
			result += "\n" + val + ","
		}
		result += "\n]"
		if v.Type().Elem().Kind() == vdl.Byte {
			return "new Uint8Array(" + result + ")"
		}
		return result
	case vdl.Set:
		result := "new Set(["
		for _, key := range vdl.SortValuesAsString(v.Keys()) {
			result += "\n  " + untypedConst(names, key) + ", "
		}
		result += "])"
		return result
	case vdl.Map:
		result := "new Map(["
		for i, key := range vdl.SortValuesAsString(v.Keys()) {
			if i > 0 {
				result += ","
			}
			result += fmt.Sprintf("\n  [%s, %s]",
				untypedConst(names, key),
				untypedConst(names, v.MapIndex(key)))

		}
		result += "])"
		return result
	case vdl.Struct:
		result := "{"
		t := v.Type()
		for ix := 0; ix < t.NumField(); ix++ {
			result += "\n  '" +
				vdlutil.FirstRuneToLower(t.Field(ix).Name) +
				"': " +
				untypedConst(names, v.StructField(ix)) +
				","
		}
		return result + "\n}"
	case vdl.Union:
		ix, innerVal := v.UnionField()
		return fmt.Sprintf("{ %q: %v }", vdlutil.FirstRuneToLower(v.Type().Field(ix).Name), untypedConst(names, innerVal))
	case vdl.TypeObject:
		return names.LookupType(v.TypeObject())
	default:
		panic(fmt.Errorf("vdl: untypedConst unhandled type %v %v", v.Kind(), v.Type()))
	}
}

func primitiveWithOptionalName(primitive, name string) string {
	if name == "" {
		return "Types." + primitive
	}
	return "new vdl.Type({kind: Kind." + primitive + ", name: '" + name + "'})"
}

// typedConst returns a javascript string representing a const that is always
// wrapped with type information
func typedConst(names typeNames, v *vdl.Value) string {
	switch v.Kind() {
	case vdl.Any, vdl.TypeObject:
		return untypedConst(names, v)
	default:
		// We call canonicalize.reduce so that we convert to native types
		// The constructor would have done the reduction of the field values
		// but it doesn't convert to native types.
		return fmt.Sprintf("canonicalize.reduce(new %s(%s, true), %s)",
			names.LookupConstructor(v.Type()),
			untypedConst(names, v),
			names.LookupType(v.Type()))
	}
}

// Returns a Not Implemented stub for the method
func generateMethodStub(method *compile.Method) string {
	args := "ctx"
	for _, arg := range method.InArgs {
		args += fmt.Sprintf(", %s", arg.Name)
	}

	return fmt.Sprintf(`function(%s) {
  throw new Error('Method %s not implemented');
}`, args, method.Name)
}

// Returns the JS version of the method signature.
func generateMethodSignature(method *compile.Method, names typeNames) string {
	return fmt.Sprintf(`{
    name: '%s',
    doc: %s,
    inArgs: %s,
    outArgs: %s,
    inStream: %s,
    outStream: %s,
    tags: %s
  }`,
		method.Name,
		quoteStripDoc(method.Doc),
		generateMethodArguments(method.InArgs, names),
		generateMethodArguments(method.OutArgs, names),
		generateMethodStreaming(method.InStream, names),
		generateMethodStreaming(method.OutStream, names),
		genMethodTags(names, method))
}

// Returns a slice describing the method's arguments.
func generateMethodArguments(args []*compile.Field, names typeNames) string {
	ret := "["
	for _, arg := range args {
		ret += fmt.Sprintf(
			`{
      name: '%s',
      doc: %s,
      type: %s
    },
    `, arg.Name, quoteStripDoc(arg.Doc), names.LookupType(arg.Type))
	}
	ret += "]"
	return ret
}

// Returns the VOM type of the stream.
func generateMethodStreaming(streaming *vdl.Type, names typeNames) string {
	if streaming == nil {
		return "null"
	}
	return fmt.Sprintf(
		`{
      name: '',
      doc: '',
      type: %s
    }`,
		names.LookupType(streaming))
}

// Returns a slice of embeddings with the proper qualified identifiers.
func generateEmbeds(embeds []*compile.Interface) string {
	result := "["
	for _, embed := range embeds {
		result += fmt.Sprintf(`{
      name: '%s',
      pkgPath: '%s',
      doc: %s
    },
    `, embed.Name, embed.File.Package.Path, quoteStripDoc(embed.Doc))
	}
	result += "]"
	return result
}

func importPath(data data, path string) string {
	// We need to prefix all of these paths with a ./ to tell node that the path is relative to
	// the current directory.  Sadly filepath.Join(".", foo) == foo, so we have to do it
	// explicitly.
	return "." + string(filepath.Separator) + data.GenerateImport(path)
}

func quoteStripDoc(doc string) string {
	// TODO(alexfandrianto): We need to handle '// ' and '\n' in the docstring.
	// It would also be nice to single-quote the whole string.
	trimmed := strings.Trim(doc, "\n")
	return strconv.Quote(trimmed)
}

func hasErrors(pkg *compile.Package) bool {
	for _, file := range pkg.Files {
		if len(file.ErrorDefs) > 0 {
			return true
		}
	}
	return false
}

func hasConsts(pkg *compile.Package) bool {
	for _, file := range pkg.Files {
		if len(file.ConstDefs) > 0 {
			return true
		}
	}
	return false
}

func generateSystemImports(data data) string {
	res := "var vdl = require('"
	packagePrefix := ""
	if data.PathToCoreJS != "" {
		packagePrefix = strings.Repeat("../", strings.Count(data.Pkg.Path, "/")+1) + data.PathToCoreJS
	}
	if data.PathToCoreJS != "" {
		res += packagePrefix + "/vdl');"
	} else {
		res += "vanadium').vdl;"
	}
	res += "\n"
	if hasErrors(data.Pkg) {
		if data.PathToCoreJS != "" {
			res += "var makeError = require('" + packagePrefix + "/errors/make-errors');\n"
			res += "var actions = require('" + packagePrefix + "/errors/actions');\n"
		} else {
			res += "var makeError = require('vanadium').makeError;\n"
			res += "var actions = require('vanadium').errorActions;\n"
		}
	}

	if hasConsts(data.Pkg) {
		if data.PathToCoreJS != "" {
			res += "var canonicalize = require('" + packagePrefix + "/vdl/canonicalize');\n"
		} else {
			res += "var canonicalize = require('vanadium').vdl.Canonicalize;\n"
		}
	}
	return res
}

func init() {
	funcMap := template.FuncMap{
		"firstRuneToLower":          vdlutil.FirstRuneToLower,
		"genMethodTags":             genMethodTags,
		"makeTypeDefinitionsString": makeTypeDefinitionsString,
		"typedConst":                typedConst,
		"generateEmbeds":            generateEmbeds,
		"generateMethodStub":        generateMethodStub,
		"generateMethodSignature":   generateMethodSignature,
		"importPath":                importPath,
		"quoteStripDoc":             quoteStripDoc,
		"generateErrorConstructor":  generateErrorConstructor,
		"generateSystemImports":     generateSystemImports,
	}
	javascriptTemplate = template.Must(template.New("genJS").Funcs(funcMap).Parse(genJS))
}

// The template that we execute against a compile.Package instance to generate our
// code.  Most of this is fairly straightforward substitution and ranges; more
// complicated logic is delegated to the helper functions above.
//
// We try to generate code that has somewhat reasonable formatting.
const genJS = `{{with $data := .}}// This file was auto-generated by the vanadium vdl tool.
{{generateSystemImports $data}}

{{/* Define additional imported modules. */}}
{{$pkg := $data.Pkg}}
{{if $data.UserImports}}{{range $imp := $data.UserImports}}
var {{$imp.Local}} = require('{{importPath $data $imp.Path}}');{{end}}{{end}}

module.exports = {};


{{/* Define any types introduced by the VDL file. */}}
// Types:
{{makeTypeDefinitionsString $data.TypeNames }}


{{/* Define all constants as typed constants. */}}
// Consts:
{{range $file := $pkg.Files}}{{range $const := $file.ConstDefs}}
  module.exports.{{$const.Name}} = {{typedConst $data.TypeNames $const.Value}};
{{end}}{{end}}

{{/* Define all errors. */}}
// Errors:
{{range $file := $pkg.Files}}{{range $error := $file.ErrorDefs}}
{{generateErrorConstructor $data.TypeNames $error}}
{{end}}{{end}}

{{/* Define each of those service interfaces here, including method stubs and
     service signature. */}}
// Services:
{{range $file := $pkg.Files}}
  {{range $iface := $file.Interfaces}}
    {{/* Define the service interface. */}}
function {{$iface.Name}}(){}
module.exports.{{$iface.Name}} = {{$iface.Name}}

    {{range $method := $iface.AllMethods}}
      {{/* Add each method to the service prototype. */}}
{{$iface.Name}}.prototype.{{firstRuneToLower $method.Name}} = {{generateMethodStub $method}};
    {{end}} {{/* end range $iface.AllMethods */}}

    {{/* The service signature encodes the same info as signature.Interface.
         TODO(alexfandrianto): We want to associate the signature type here, but
         it's complicated. https://github.com/veyron/release-issues/issues/432
         For now, we need to pass the type in manually into encode. */}}
{{$iface.Name}}.prototype._serviceDescription = {
  name: '{{$iface.Name}}',
  pkgPath: '{{$pkg.Path}}',
  doc: {{quoteStripDoc $iface.Doc}},
  embeds: {{generateEmbeds $iface.Embeds}},
  methods: [
    {{range $method := $iface.AllMethods}}
      {{/* Each method signature contains the information in ipc.MethodSig. */}}
    {{generateMethodSignature $method $data.TypeNames}},
    {{end}} {{/*end range $iface.AllMethods*/}}
  ]
};

  {{end}} {{/* end range $files.Interfaces */}}
{{end}} {{/* end range $pkg.Files */}}


{{end}}`
