// 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.TypedStream<{{ $method.SendType }}, {{ $method.RecvType }}> _stream = new io.v.v23.vdl.TypedStream<{{ $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(),
	}
}
