// Copyright 2018 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 C++
package source_generator

import (
	"sort"
	"strings"
)

type CPP struct{}

// Gets header guards of the form:
//
// COBALT_REGISTRY_{PROJECT_NAME}_{CUSTOMER_NAME}_{NAMESPACE}_GEN_
func getHeaderGuard(projectName, customerName string, namespaces []string) string {
	base := toUpperSnakeCase("cobalt", "registry", projectName, customerName)
	if len(namespaces) > 0 {
		base = toUpperSnakeCase(base, strings.Join(namespaces, " "))
	}
	return toUpperSnakeCase(base, "gen") + "_"
}

func (_ CPP) getCommentPrefix() string { return "//" }
func (_ CPP) supportsTypeAlias() bool  { return true }

func (_ CPP) writeExtraHeader(so *sourceOutputter, projectName, customerName string, namespaces []string) {
	if projectName == "" || customerName == "" {
		so.writeLine("#pragma once")
	} else {
		guard := getHeaderGuard(projectName, customerName, namespaces)
		so.writeLine("#ifndef " + guard)
		so.writeLine("#define " + guard)
	}
	so.writeLine("")
	so.writeLine("#include <stdint.h>")
	so.writeLine("")
	if so.options.shouldGenerateNameMaps() {
		so.writeLine("#include <map>")
		so.writeLine("#include <string>")
	}
	so.writeLine("#include <vector>")
	so.writeLine("")
}

func (_ CPP) writeExtraFooter(so *sourceOutputter, projectName, customerName string, namespaces []string) {
	if projectName != "" && customerName != "" {
		so.writeLine("")
		so.writeLine("#endif  // " + getHeaderGuard(projectName, customerName, namespaces))
	}
}

func enumNamespace(name ...string) string {
	name = append(name, "internal scope do not use")
	return "__" + toSnakeCase(name...) + "__"
}

func (_ CPP) writeEnumBegin(so *sourceOutputter, name ...string) {
	so.writeLineFmt("namespace %s {", enumNamespace(name...))
	so.writeLine("enum Enum {")
}

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

// C++ allows duplicate keys in an enum, so nothing needs to be done here.
func (_ CPP) writeEnumAliasesBegin(so *sourceOutputter, name ...string) {
}

func (_ CPP) writeEnumAlias(so *sourceOutputter, name, from, to []string) {
	so.writeLineFmt("  %s = %s,", toPascalCase(to...), toPascalCase(from...))
}

func (_ CPP) writeEnumEnd(so *sourceOutputter, name ...string) {
	so.writeLine("};")
	so.writeLineFmt("}  // %s", enumNamespace(name...))

	so.writeLineFmt("using %s = %s::Enum;", toPascalCase(name...), enumNamespace(name...))
}

func (_ CPP) writeEnumExport(so *sourceOutputter, enumName, name []string) {
	enum := toPascalCase(enumName...)
	variant := toPascalCase(name...)
	so.writeLineFmt("inline constexpr %s %s_%s = %s::%s;", enum, enum, variant, enum, variant)
}

func (_ CPP) writeTypeAlias(so *sourceOutputter, from, to []string) {
	so.writeLineFmt("using %s = %s;", toPascalCase(to...), toPascalCase(from...))
}

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

func (_ CPP) writeNamespacesBegin(so *sourceOutputter, namespaces []string, outputFilename string) {
	if len(namespaces) > 0 {
		so.writeLineFmt("namespace %s {", getNamespaces(namespaces))
	}
}

func (_ CPP) writeNamespacesEnd(so *sourceOutputter, namespaces []string, outputFilename string) {
	if len(namespaces) > 0 {
		so.writeLineFmt("}  // %s", getNamespaces(namespaces))
	}
}

func (_ CPP) writeConstUint32(so *sourceOutputter, value uint32, name ...string) {
	name = append([]string{"k"}, name...)
	so.writeLineFmt("inline constexpr uint32_t %s = %d;", toCamelCase(name...), value)
}

func (_ CPP) writeConstInt64(so *sourceOutputter, value int64, name ...string) {
	name = append([]string{"k"}, name...)
	so.writeLineFmt("inline constexpr int64_t %s = %d;", toCamelCase(name...), value)
}

func (_ CPP) writeConstMap(so *sourceOutputter, value map[uint32]string, name ...string) {
	name = append([]string{"k"}, name...)
	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("inline const std::map<std::string, uint32_t> %s = {", toCamelCase(name...))
	for _, id := range keys {
		dimensionValue := value[id]
		so.writeLineFmt("    {\"%s\", %d},", dimensionValue, id)
	}
	so.writeLineFmt("};")
}

func (_ CPP) writeStringConstant(so *sourceOutputter, value string, name ...string) {
	name = append([]string{"k"}, name...)
	so.writeLineFmt("inline constexpr char %s[] = \"%s\";", toCamelCase(name...), value)
}

func (_ CPP) writeStructBegin(so *sourceOutputter, name ...string) {
	so.writeLineFmt("struct %s {", toPascalCase(name...))
}

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

func (_ CPP) writeToVectorMethod(so *sourceOutputter, structName []string, fields [][]string) {
	so.writeLine("")
	so.writeLineFmt("  [[nodiscard]] std::vector<uint32_t> ToVector() const {")
	so.writeLine("    return {")
	for _, field := range fields {
		so.writeLineFmt("      %s,", toSnakeCase(field...))
	}
	so.writeLine("    };")
	so.writeLine("  }")
}

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

// Returns an output formatter that will output the contents of a C++ header
// 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 forTesting is true, a constant will be generated for each report ID, based on the report's name.
func CppOutputFactory(varName string, namespace []string, options generatorOptions) OutputFormatter {
	return newSourceOutputterWithNamespaces(CPP{}, varName, namespace, options).getOutputFormatter()
}
