// 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 Rust
package source_generator

import (
	"fmt"
	"sort"
)

type Rust struct{}

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

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

// See: https://doc.rust-lang.org/reference/keywords.html
var rustIdents = [...]string{
	"as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn", "for", "if",
	"impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref", "return", "self",
	"Self", "static", "struct", "super", "trait", "true", "type", "unsafe", "use", "where", "while",
	"async", "await", "dyn", "abstract", "become", "box", "do", "final", "macro", "override", "priv",
	"typeof", "unsized", "virtual", "yield", "try",
}

func escapeIdent(value string) string {
	for _, ident := range rustIdents {
		if ident == value {
			return fmt.Sprintf("r#%s", value)
		}
	}
	return value
}

func (_ Rust) writeEnumBegin(so *sourceOutputter, name ...string) {
	so.writeLine("#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]")
	so.writeLineFmt("pub enum %s {", toPascalCase(name...))
}

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

func (_ Rust) writeEnumAliasesBegin(so *sourceOutputter, name ...string) {
	so.writeLine("}")
	so.writeLineFmt("impl %s {", toPascalCase(name...))
}

func (_ Rust) writeEnumAlias(so *sourceOutputter, name, from, to []string) {
	so.writeLine("  #[allow(non_upper_case_globals)]")
	so.writeLineFmt("  pub const %s: %s = %s::%s;", toPascalCase(to...), toPascalCase(name...), toPascalCase(name...), toPascalCase(from...))
}

func (_ Rust) writeEnumEnd(so *sourceOutputter, name ...string) {
	so.writeLine("}")
	so.writeLine("")
	so.writeLineFmt("impl cobalt_client::traits::AsEventCode for %s {", toPascalCase(name...))
	so.writeLine("  fn as_event_code(&self) -> u32 {")
	so.writeLine("    *self as u32")
	so.writeLine("  }")
	so.writeLine("}")

}

// We don't alias Enums in rust, since this can easily be accomplished with a
// use EnumName::*;
func (_ Rust) writeEnumExport(so *sourceOutputter, enumName, name []string) {}

func (_ Rust) writeTypeAlias(so *sourceOutputter, from, to []string) {
	so.writeLineFmt("pub use %s as %s;", toPascalCase(from...), toPascalCase(to...))
}

func (_ Rust) writeNamespacesBegin(so *sourceOutputter, namespaces []string, outputFilename string) {
	if len(namespaces) > 0 {
		for _, ns := range namespaces {
			so.writeLineFmt("pub mod %s {", escapeIdent(toSnakeCase(ns)))
		}
	}
}

func (_ Rust) writeNamespacesEnd(so *sourceOutputter, namespaces []string, outputFilename string) {
	if len(namespaces) > 0 {
		for _, _ = range namespaces {
			so.writeLine("}")
		}
	}
}

func (_ Rust) writeConstUint32(so *sourceOutputter, value uint32, name ...string) {
	so.writeLineFmt("pub const %s: u32 = %d;", toUpperSnakeCase(name...), value)
}

func (_ Rust) writeConstInt64(so *sourceOutputter, value int64, name ...string) {
	so.writeLineFmt("pub const %s: i64 = %d;", toUpperSnakeCase(name...), value)
}

func (_ Rust) 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("pub const %s: [(&'static str, u32); %d] = [", toUpperSnakeCase(name...), len(keys))
	for _, id := range keys {
		dimensionValue := value[id]
		so.writeLineFmt("    (\"%s\", %d),", dimensionValue, id)
	}
	so.writeLineFmt("];")
}

func (_ Rust) writeStringConstant(so *sourceOutputter, value string, name ...string) {
	so.writeLineFmt("pub const %s: &str = \"%s\";", toUpperSnakeCase(name...), value)
}

func (_ Rust) writeStructBegin(so *sourceOutputter, name ...string) {
	so.writeLine("#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]")
	so.writeLineFmt("pub struct %s {", toPascalCase(name...))
}

func (_ Rust) writeStructField(so *sourceOutputter, name, typeName []string) {
	so.writeLineFmt("  pub %s: %s,", escapeIdent(toSnakeCase(name...)), escapeIdent(toPascalCase(typeName...)))
}

func (_ Rust) writeToVectorMethod(so *sourceOutputter, structName []string, fields [][]string) {
	so.writeLine("}")
	so.writeLine("")
	so.writeLineFmt("impl cobalt_client::traits::AsEventCodes for %s {", toPascalCase(structName...))
	so.writeLine("  fn as_event_codes(&self) -> Vec<u32> {")
	so.writeLine("    use cobalt_client::traits::AsEventCode;")
	so.writeLine("    vec![")
	for _, field := range fields {
		so.writeLineFmt("      self.%s.as_event_code(),", escapeIdent(toSnakeCase(field...)))
	}
	so.writeLine("    ]")
	so.writeLine("  }")
}

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

// 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 RustOutputFactory(varName string, namespace []string, options generatorOptions) OutputFormatter {
	return newSourceOutputterWithNamespaces(Rust{}, varName, namespace, options).getOutputFormatter()
}
