// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file implements outputLanguage for Java
package source_generator

import (
	"sort"
	"strings"
)

type Java struct{}

func (_ Java) getCommentPrefix() string { return "  //" }
func (_ Java) supportsTypeAlias() bool  { return false }

func getPackageName(namespaces []string) string {
	ns := make([]string, len(namespaces))
	for i, v := range namespaces {
		ns[i] = toSnakeCase(v)
	}
	return strings.Join(ns, ".")
}

func (_ Java) writeExtraHeader(so *sourceOutputter, projectName, customerName string, namespaces []string) {
	if len(namespaces) > 0 {
		so.writeLineFmt("package %s;", getPackageName(namespaces))
	}
	so.writeLine("")
	so.writeLine("import java.util.Arrays;")
	so.writeLine("import java.util.List;")
	if so.options.shouldGenerateNameMaps() {
		so.writeLine("import java.util.Map;")
		so.writeLine("import static java.util.Map.entry;")
	}
}

func (_ Java) writeExtraFooter(so *sourceOutputter, projectName, customerName string, namespaces []string) {
}

func (_ Java) writeEnumBegin(so *sourceOutputter, name ...string) {
	so.writeLineFmt("  public static enum %s {", toPascalCase(name...))
}

func (_ Java) writeEnumEntry(so *sourceOutputter, value uint32, name ...string) {
	so.writeLineFmt("    %s(%d),", toUpperSnakeCase(name...), value)
}

func (_ Java) writeEnumAliasesBegin(so *sourceOutputter, name ...string) {}

func (_ Java) writeEnumAlias(so *sourceOutputter, name, from, to []string) {
	so.writeLineFmt("    %s(%s.code),", toUpperSnakeCase(to...), toUpperSnakeCase(from...))
}

func (_ Java) writeEnumEnd(so *sourceOutputter, name ...string) {
	so.writeLine("    ;")
	so.writeLine("")
	so.writeLine("    private final int code;")
	so.writeLine("")
	so.writeLineFmt("    private %s(int code) {", toPascalCase(name...))
	so.writeLine("      this.code = code;")
	so.writeLine("    }")
	so.writeLine("")
	so.writeLine("    public int getCode() {")
	so.writeLine("      return code;")
	so.writeLine("    }")
	so.writeLine("  }")
}

func (_ Java) writeEnumExport(so *sourceOutputter, enumName, name []string) {
	variant := toUpperSnakeCase(name...)
	so.writeLineFmt("  public static final int %s_%s = %s.%s.code;", toUpperSnakeCase(enumName...), variant, toPascalCase(enumName...), variant)
}

func (_ Java) writeTypeAlias(so *sourceOutputter, from, to []string) {}

func (_ Java) writeNamespacesBegin(so *sourceOutputter, namespaces []string, outputFilename string) {
	so.writeLine("")
	so.writeLine("/** Constants defined in the Cobalt Registry. */")
	so.writeLine("@SuppressWarnings(\"javadoc\")")
	so.writeLine("@javax.annotation.Generated(\"https://fuchsia.googlesource.com/cobalt/+/refs/heads/master/src/bin/config_parser/src/source_generator/\")")
	so.writeLineFmt("public final class %s {", toPascalCase(outputFilename))
}

func (_ Java) writeNamespacesEnd(so *sourceOutputter, namespaces []string, outputFilename string) {
	so.writeLine("  /** Private constructor to prevent instantiation of static class. */")
	so.writeLineFmt("  private %s() {}", toPascalCase(outputFilename))
	so.writeLine("}")
}

func (_ Java) writeConstUint32(so *sourceOutputter, value uint32, name ...string) {
	so.writeLineFmt("  public static final long %s = %dL;", toUpperSnakeCase(name...), value)
}

func (_ Java) writeConstInt64(so *sourceOutputter, value int64, name ...string) {
	so.writeLineFmt("  public static final long %s = %dL;", toUpperSnakeCase(name...), value)
}

func (_ Java) writeConstMap(so *sourceOutputter, value map[uint32]string, name ...string) {

	var keys []uint32
	for k := range value {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })

	so.writeLineFmt("  public static Map<String, long> %s = Map.ofEntries(", toUpperSnakeCase(name...))
	for _, id := range keys {
		dimensionValue := value[id]
		so.writeLineFmt("    entry(\"%s\", %d),", dimensionValue, id)
	}
	so.writeLineFmt("  );")
}

func (_ Java) writeStringConstant(so *sourceOutputter, value string, name ...string) {
	so.writeLineFmt("  public static final String %s = \"%s\";", toUpperSnakeCase(name...), value)
}

func (_ Java) writeStructBegin(so *sourceOutputter, name ...string) {
	so.writeLineFmt("  public static class %s {", toPascalCase(name...))
}

func (_ Java) writeStructField(so *sourceOutputter, name, typeName []string) {
	so.writeLineFmt("    public %s %s;", toPascalCase(typeName...), toCamelCase(name...))
}

func (_ Java) writeToVectorMethod(so *sourceOutputter, structName []string, fields [][]string) {
	so.writeLine("")
	so.writeLine("    public List<Integer> toList() {")
	so.writeLineFmt("      return Arrays.asList(")
	for i, field := range fields {
		suffix := ","
		if i == len(fields)-1 {
			suffix = ""
		}
		so.writeLineFmt("        %s.code%s", toCamelCase(field...), suffix)
	}
	so.writeLineFmt("      );")
	so.writeLine("    }")
}

func (_ Java) writeStructEnd(so *sourceOutputter) {
	so.writeLine("  }")
}

// Returns an output formatter that will output the contents of a Java source
// file that contains a variable declaration for a string literal that contains
// the base64-encoding of the serialized proto.
//
// varName will be the name of the variable containing the base64-encoded serialized proto.
// namespace is a list of nested namespaces inside of which the variable will be defined.
// If features contains "testing", constants will also be generated for each report.
func JavaOutputFactory(varName string, namespace []string, options generatorOptions, outFilename string) OutputFormatter {
	return newSourceOutputterWithNamespacesAndFilename(Java{}, varName, namespace, options, outFilename).getOutputFormatter()
}
