// 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 (
	"bytes"
	"log"

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

const errorTmpl = header + `
// Source(s): {{ .Source }}
package {{ .PackagePath }};


public final class {{ .ClassName }} {
    {{ range $file := .Files }}

    /* The following errors originate in file: {{ $file.Name }} */
    {{/*Error Defs*/}}
    {{ range $error := $file.Errors }}
    {{ $error.Doc }}
    {{ $error.AccessModifier }} static final io.v.v23.verror.VException.IDAction {{ $error.Name }} = io.v.v23.verror.VException.register("{{ $error.ID }}", io.v.v23.verror.VException.ActionCode.{{ $error.ActionName }}, "{{ $error.EnglishFmt }}");
    {{ end }} {{/* range $file.Errors */}}

    {{ end }} {{/* range .Files */}}

    static {
        {{ range $file := .Files }}
        /* The following errors originate in file: {{ $file.Name }} */
        {{ range $error := $file.Errors }}
        {{ range $format := $error.Formats}}
        io.v.v23.i18n.Language.getDefaultCatalog().setWithBase("{{ $format.Lang }}", {{ $error.Name }}.getID(), "{{ $format.Fmt }}");
        {{ end }} {{/* range $error.Formats */}}
        {{ end }} {{/* range $file.Errors */}}
        {{ end }} {{/* range .Files */}}
    }

    {{ range $file := .Files }}
    /* The following error creator methods originate in file: {{ $file.Name }} */
    {{ range $error := $file.Errors }}
    /**
     * Creates an error with {@code {{ $error.Name }}} identifier.
     */
    public static io.v.v23.verror.VException {{ $error.MethodName }}(io.v.v23.context.VContext _ctx{{ $error.MethodArgs}}) {
        final java.lang.Object[] _params = new java.lang.Object[] { {{ $error.Params }} };
        final java.lang.reflect.Type[] _paramTypes = new java.lang.reflect.Type[]{ {{ $error.ParamTypes }} };
        return io.v.v23.verror.VException.make({{ $error.Name }}, _ctx, _paramTypes, _params);
    }
    {{ end }} {{/* range $file.Errors */}}
    {{ end }} {{/* range .Files */}}
}
`

type errorDef struct {
	AccessModifier string
	Doc            string
	Name           string
	ID             string
	ActionName     string
	EnglishFmt     string
	Formats        []errorFormat
	MethodName     string
	MethodArgs     string
	Params         string
	ParamTypes     string
}

type errorFormat struct {
	Lang string
	Fmt  string
}

type errorFile struct {
	Name   string
	Errors []errorDef
}

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

// genJavaErrorFile generates the (single) Java file that contains error
// definitions from all the VDL files.
func genJavaErrorFile(pkg *compile.Package, env *compile.Env) *JavaFileInfo {
	if !shouldGenerateErrorFile(pkg) {
		return nil
	}

	className := "Errors"

	files := make([]errorFile, len(pkg.Files))
	for i, file := range pkg.Files {
		errors := make([]errorDef, len(file.ErrorDefs))
		for j, err := range file.ErrorDefs {
			formats := make([]errorFormat, len(err.Formats))
			for k, format := range err.Formats {
				formats[k].Lang = string(format.Lang)
				formats[k].Fmt = format.Fmt
			}
			errors[j].AccessModifier = accessModifierForName(err.Name)
			errors[j].Doc = javaDoc(err.Doc)
			errors[j].Name = vdlutil.ToConstCase(err.Name)
			errors[j].ID = err.ID
			errors[j].ActionName = vdlutil.ToConstCase(err.RetryCode.String())
			errors[j].EnglishFmt = err.English
			errors[j].Formats = formats
			errors[j].MethodName = "make" + vdlutil.FirstRuneToUpper(err.Name)
			errors[j].MethodArgs = javaDeclarationArgStr(err.Params, env, true)
			errors[j].Params = javaCallingArgStr(err.Params, false)
			errors[j].ParamTypes = javaCallingArgTypeStr(err.Params, env)
		}
		files[i].Name = file.BaseName
		files[i].Errors = errors
	}

	data := struct {
		FileDoc     string
		ClassName   string
		Source      string
		PackagePath string
		Files       []errorFile
	}{
		FileDoc:     pkg.FileDoc,
		ClassName:   className,
		Source:      javaFileNames(pkg.Files),
		PackagePath: javaPath(javaGenPkgPath(pkg.GenPath)),
		Files:       files,
	}
	var buf bytes.Buffer
	err := parseTmpl("error", errorTmpl).Execute(&buf, data)
	if err != nil {
		log.Fatalf("vdl: couldn't execute error template: %v", err)
	}
	return &JavaFileInfo{
		Name: className + ".java",
		Data: buf.Bytes(),
	}
}
