// 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"
	"path"
	"strings"

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

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

/**
 * Wrapper for {@link {{ .ServiceName }}Server}.  This wrapper is used by
 * {@link io.v.v23.rpc.ReflectInvoker} to indirectly invoke server methods.
 */
public final class {{ .ServiceName }}ServerWrapper {
    private final {{ .FullServiceName }}Server server;

{{/* Define fields to hold each of the embedded server wrappers*/}}
{{ range $embed := .Embeds }}
    {{/* e.g. private final com.somepackage.gen_impl.ArithStub stubArith; */}}
    private final {{ $embed.FullName }}ServerWrapper wrapper{{ $embed.Name }};
    {{ end }}

    /**
     * Creates a new {@link {{ .ServiceName }}ServerWrapper} to invoke the methods of the
     * provided server.
     *
     * @param server server whose methods are to be invoked
     */
    public {{ .ServiceName }}ServerWrapper({{ .FullServiceName }}Server server) {
        this.server = server;
        {{/* Initialize the embeded server wrappers */}}
        {{ range $embed := .Embeds }}
        this.wrapper{{ $embed.Name }} = new {{ $embed.FullName }}ServerWrapper(server);
        {{ end }}
    }

    /**
     * Returns a description of this server.
     */
    public io.v.v23.vdlroot.signature.Interface signature() {
        java.util.List<io.v.v23.vdlroot.signature.Embed> embeds = new java.util.ArrayList<io.v.v23.vdlroot.signature.Embed>();
        java.util.List<io.v.v23.vdlroot.signature.Method> methods = new java.util.ArrayList<io.v.v23.vdlroot.signature.Method>();
        {{ range $method := .Methods }}
        {
            java.util.List<io.v.v23.vdlroot.signature.Arg> inArgs = new java.util.ArrayList<io.v.v23.vdlroot.signature.Arg>();
            {{ range $arg := $method.CallingArgTypes }}
            inArgs.add(new io.v.v23.vdlroot.signature.Arg("", "", new io.v.v23.vdl.VdlTypeObject({{ $arg }})));
            {{ end }}
            java.util.List<io.v.v23.vdlroot.signature.Arg> outArgs = new java.util.ArrayList<io.v.v23.vdlroot.signature.Arg>();
            {{ range $arg := $method.RetJavaTypes }}
            outArgs.add(new io.v.v23.vdlroot.signature.Arg("", "", new io.v.v23.vdl.VdlTypeObject({{ $arg }})));
            {{ end }}
            java.util.List<io.v.v23.vdl.VdlAny> tags = new java.util.ArrayList<io.v.v23.vdl.VdlAny>();
            {{ range $tag := .Tags }}
            tags.add(new io.v.v23.vdl.VdlAny(io.v.v23.vdl.VdlValue.valueOf({{ $tag.Value }}, {{ $tag.Type }})));
            {{ end }}
            methods.add(new io.v.v23.vdlroot.signature.Method(
                "{{ $method.Name }}",
                "{{ $method.Doc }}",
                inArgs,
                outArgs,
                null,
                null,
                tags));
        }
        {{ end }}

        return new io.v.v23.vdlroot.signature.Interface("{{ .ServiceName }}", "{{ .PackagePath }}", "{{ .Doc }}", embeds, methods);
    }

    /**
     * Returns all tags associated with the provided method or {@code null} if the method isn't
     * implemented by this server.
     *
     * @param method method whose tags are to be returned
     */
    @SuppressWarnings("unused")
    public io.v.v23.vdl.VdlValue[] getMethodTags(java.lang.String method) throws io.v.v23.verror.VException {
        {{ range $methodName, $tags := .MethodTags }}
        if ("{{ $methodName }}".equals(method)) {
            try {
                return new io.v.v23.vdl.VdlValue[] {
                    {{ range $tag := $tags }} io.v.v23.vdl.VdlValue.valueOf({{ $tag.Value }}, {{ $tag.Type }}), {{ end }}
                };
            } catch (IllegalArgumentException e) {
                throw new io.v.v23.verror.VException(String.format("Couldn't get tags for method \"{{ $methodName }}\": %s", e.getMessage()));
            }
        }
        {{ end }}
        {{ range $embed := .Embeds }}
        {
            io.v.v23.vdl.VdlValue[] tags = this.wrapper{{ $embed.Name }}.getMethodTags(method);
            if (tags != null) {
                return tags;
            }
        }
        {{ end }}
        return null;  // method not found
    }

     {{/* Iterate over methods defined directly in the body of this server */}}
    {{ range $method := .Methods }}
    {{ $method.JavaDoc }}
    public {{ $method.RetType }} {{ $method.Name }}(io.v.v23.context.VContext ctx, final io.v.v23.rpc.StreamServerCall call{{ $method.DeclarationArgs }}) throws io.v.v23.verror.VException {
        {{ if $method.IsStreaming }}
        io.v.v23.vdl.Stream<{{ $method.SendType }}, {{ $method.RecvType }}> _stream = new io.v.v23.vdl.Stream<{{ $method.SendType }}, {{ $method.RecvType }}>() {
            @Override
            public void send({{ $method.SendType }} item) throws io.v.v23.verror.VException {
                java.lang.reflect.Type type = new com.google.common.reflect.TypeToken< {{ $method.SendType }} >() {}.getType();
                call.send(item, type);
            }
            @Override
            public {{ $method.RecvType }} recv() throws java.io.EOFException, io.v.v23.verror.VException {
                java.lang.reflect.Type type = new com.google.common.reflect.TypeToken< {{ $method.RecvType }} >() {}.getType();
                java.lang.Object result = call.recv(type);
                try {
                    return ({{ $method.RecvType }})result;
                } catch (java.lang.ClassCastException e) {
                    throw new io.v.v23.verror.VException("Unexpected result type: " + result.getClass().getCanonicalName());
                }
            }
        };
        {{ end }} {{/* end if $method.IsStreaming */}}
        {{ if $method.Returns }} return {{ end }} this.server.{{ $method.Name }}(ctx, call {{ $method.CallingArgs }} {{ if $method.IsStreaming }} ,_stream {{ end }} );
    }
{{end}}

{{/* Iterate over methods from embeded servers and generate code to delegate the work */}}
{{ range $eMethod := .EmbedMethods }}
    {{ $eMethod.JavaDoc }}
    public {{ $eMethod.RetType }} {{ $eMethod.Name }}(io.v.v23.context.VContext ctx, io.v.v23.rpc.StreamServerCall call{{ $eMethod.DeclarationArgs }}) throws io.v.v23.verror.VException {
        {{/* e.g. return this.stubArith.cosine(ctx, call, [args], options) */}}
        {{ if $eMethod.Returns }}return{{ end }}  this.wrapper{{ $eMethod.IfaceName }}.{{ $eMethod.Name }}(ctx, call{{ $eMethod.CallingArgs }});
    }
{{ end }} {{/* end range .EmbedMethods */}}

}
`

type serverWrapperMethod struct {
	CallingArgs     string
	CallingArgTypes []string
	DeclarationArgs string
	Doc             string
	IsStreaming     bool
	JavaDoc         string
	Name            string
	RecvType        string
	RetType         string
	RetJavaTypes    []string
	Returns         bool
	SendType        string
	Tags            []methodTag
}

type serverWrapperEmbedMethod struct {
	CallingArgs     string
	DeclarationArgs string
	Doc             string
	IfaceName       string
	JavaDoc         string
	Name            string
	RetType         string
	Returns         bool
}

type serverWrapperEmbed struct {
	Name     string
	FullName string
}

type methodTag struct {
	Value string
	Type  string
}

// TODO(sjr): move this to somewhere in util_*.
func toJavaString(goString string) string {
	result := strings.Replace(goString, "\"", "\\\"", -1)
	result = strings.Replace(result, "\n", "\" + \n\"", -1)
	return result
}

func processServerWrapperMethod(iface *compile.Interface, method *compile.Method, env *compile.Env, tags []methodTag) serverWrapperMethod {
	callArgTypes := make([]string, len(method.InArgs))
	for i, arg := range method.InArgs {
		callArgTypes[i] = javaReflectType(arg.Type, env)
	}
	retArgTypes := make([]string, len(method.OutArgs))
	for i, arg := range method.OutArgs {
		retArgTypes[i] = javaReflectType(arg.Type, env)
	}
	return serverWrapperMethod{
		CallingArgs:     javaCallingArgStr(method.InArgs, true),
		CallingArgTypes: callArgTypes,
		DeclarationArgs: javaDeclarationArgStr(method.InArgs, env, true),
		Doc:             toJavaString(method.Doc),
		IsStreaming:     isStreamingMethod(method),
		JavaDoc:         javaDoc(method.Doc, method.DocSuffix),
		Name:            vdlutil.FirstRuneToLower(method.Name),
		RecvType:        javaType(method.InStream, true, env),
		RetType:         serverInterfaceOutArg(iface, method, env),
		RetJavaTypes:    retArgTypes,
		Returns:         len(method.OutArgs) >= 1,
		SendType:        javaType(method.OutStream, true, env),
		Tags:            tags,
	}
}

func processServerWrapperEmbedMethod(iface *compile.Interface, embedMethod *compile.Method, env *compile.Env) serverWrapperEmbedMethod {
	return serverWrapperEmbedMethod{
		CallingArgs:     javaCallingArgStr(embedMethod.InArgs, true),
		DeclarationArgs: javaDeclarationArgStr(embedMethod.InArgs, env, true),
		IfaceName:       vdlutil.FirstRuneToUpper(iface.Name),
		JavaDoc:         javaDoc(embedMethod.Doc, embedMethod.DocSuffix),
		Name:            vdlutil.FirstRuneToLower(embedMethod.Name),
		RetType:         serverInterfaceOutArg(iface, embedMethod, env),
		Returns:         len(embedMethod.OutArgs) >= 1,
	}
}

// genJavaServerWrapperFile generates a java file containing a server wrapper for the specified
// interface.
func genJavaServerWrapperFile(iface *compile.Interface, env *compile.Env) JavaFileInfo {
	embeds := []serverWrapperEmbed{}
	for _, embed := range allEmbeddedIfaces(iface) {
		embeds = append(embeds, serverWrapperEmbed{
			Name:     vdlutil.FirstRuneToUpper(embed.Name),
			FullName: javaPath(javaGenPkgPath(path.Join(embed.File.Package.GenPath, vdlutil.FirstRuneToUpper(embed.Name)))),
		})
	}
	methodTags := make(map[string][]methodTag)
	// Copy method tags off of the interface.
	methods := make([]serverWrapperMethod, len(iface.Methods))
	for i, method := range iface.Methods {
		tags := make([]methodTag, len(method.Tags))
		for j, tag := range method.Tags {
			tags[j].Value = javaConstVal(tag, env)
			tags[j].Type = javaReflectType(tag.Type(), env)
		}
		methodTags[vdlutil.FirstRuneToLower(method.Name)] = tags
		methods[i] = processServerWrapperMethod(iface, method, env, tags)
	}
	embedMethods := []serverWrapperEmbedMethod{}
	for _, embedMao := range dedupedEmbeddedMethodAndOrigins(iface) {
		embedMethods = append(embedMethods, processServerWrapperEmbedMethod(embedMao.Origin, embedMao.Method, env))
	}
	javaServiceName := vdlutil.FirstRuneToUpper(iface.Name)
	data := struct {
		FileDoc         string
		EmbedMethods    []serverWrapperEmbedMethod
		Embeds          []serverWrapperEmbed
		FullServiceName string
		Methods         []serverWrapperMethod
		MethodTags      map[string][]methodTag
		PackagePath     string
		ServiceName     string
		Source          string
		Doc             string
	}{
		FileDoc:         iface.File.Package.FileDoc,
		EmbedMethods:    embedMethods,
		Embeds:          embeds,
		FullServiceName: javaPath(interfaceFullyQualifiedName(iface)),
		Methods:         methods,
		MethodTags:      methodTags,
		PackagePath:     javaPath(javaGenPkgPath(iface.File.Package.GenPath)),
		ServiceName:     javaServiceName,
		Source:          iface.File.BaseName,
		Doc:             toJavaString(iface.NamePos.Doc),
	}
	var buf bytes.Buffer
	err := parseTmpl("server wrapper", serverWrapperTmpl).Execute(&buf, data)
	if err != nil {
		log.Fatalf("vdl: couldn't execute server wrapper template: %v", err)
	}
	return JavaFileInfo{
		Name: javaServiceName + "ServerWrapper.java",
		Data: buf.Bytes(),
	}
}
