// 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 output formatting for the cobalt config parser.

package source_generator

import (
	"bytes"
	"config"
	"fmt"
	"privacy"
	"reflect"
	"sort"
	"strconv"
	"strings"
)

type outputLanguage interface {
	getCommentPrefix() string
	supportsTypeAlias() bool

	writeExtraHeader(so *sourceOutputter, projectName, customerName string, namespaces []string)
	writeExtraFooter(so *sourceOutputter, projectName, customerName string, namespaces []string)
	writeEnumBegin(so *sourceOutputter, name ...string)
	writeEnumEntry(so *sourceOutputter, value uint32, name ...string)
	writeEnumAliasesBegin(so *sourceOutputter, name ...string)
	writeEnumAlias(so *sourceOutputter, name, from, to []string)
	writeEnumEnd(so *sourceOutputter, name ...string)
	writeEnumExport(so *sourceOutputter, enumName, name []string)
	writeTypeAlias(so *sourceOutputter, from, to []string)
	writeNamespacesBegin(so *sourceOutputter, namespaces []string, outputFilename string)
	writeNamespacesEnd(so *sourceOutputter, namespaces []string, outputFilename string)
	writeConstUint32(so *sourceOutputter, value uint32, name ...string)
	writeConstInt64(so *sourceOutputter, value int64, name ...string)
	writeConstMap(so *sourceOutputter, value map[uint32]string, name ...string)
	writeStringConstant(so *sourceOutputter, value string, name ...string)
	writeStructBegin(so *sourceOutputter, name ...string)
	writeStructField(so *sourceOutputter, name, typeName []string)
	writeToVectorMethod(so *sourceOutputter, structName []string, fields [][]string)
	writeStructEnd(so *sourceOutputter)
}

type OutputFormatter func(c, filtered *config.CobaltRegistry) (outputBytes []byte, err error)

type sourceOutputter struct {
	buffer      *bytes.Buffer
	language    outputLanguage
	varName     string
	namespaces  []string
	options     generatorOptions
	outFilename string
}

func newSourceOutputter(language outputLanguage, varName string, options generatorOptions) *sourceOutputter {
	return newSourceOutputterWithNamespaces(language, varName, []string{}, options)
}

func newSourceOutputterWithNamespaces(language outputLanguage, varName string, namespaces []string, options generatorOptions) *sourceOutputter {
	return newSourceOutputterWithNamespacesAndFilename(language, varName, namespaces, options, "")
}

func newSourceOutputterWithNamespacesAndFilename(language outputLanguage, varName string, namespaces []string, options generatorOptions, outFilename string) *sourceOutputter {
	return &sourceOutputter{
		buffer:      new(bytes.Buffer),
		language:    language,
		varName:     varName,
		namespaces:  namespaces,
		options:     options,
		outFilename: outFilename,
	}
}

func (so *sourceOutputter) writeLine(str string) {
	so.buffer.WriteString(str + "\n")
}

func (so *sourceOutputter) writeLineFmt(format string, args ...interface{}) {
	so.writeLine(fmt.Sprintf(format, args...))
}

func (so *sourceOutputter) writeComment(comment string) {
	for _, comment_line := range strings.Split(comment, "\n") {
		so.writeLineFmt("%s %s", so.language.getCommentPrefix(), strings.TrimLeft(comment_line, " "))
	}
}

func (so *sourceOutputter) writeCommentFmt(format string, args ...interface{}) {
	so.writeComment(fmt.Sprintf(format, args...))
}

func (so *sourceOutputter) writeGenerationWarning() {
	so.writeCommentFmt(`This file was generated by Cobalt's Registry parser based on the registry YAML
in the cobalt_config repository. Edit the YAML there to make changes.`)
}

type idEntry struct {
	id    uint32
	index int
}

// writeIdConstants prints out a list of constants to be used in testing. It
// uses the Name attribute of each Metric and Report to construct the constants.
//
// For a metric named "SingleString" the cpp constant would be kSingleStringMetricId
// For a report named "Test" in the "SingleString" metric, the cpp constant would be kSingleStringTestReportId
func (so *sourceOutputter) writeIdConstants(constType string, entries map[string]idEntry) {
	if len(entries) == 0 {
		return
	}
	var keys []string
	for k := range entries {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool {
		if entries[keys[i]].id != entries[keys[j]].id {
			return entries[keys[i]].id < entries[keys[j]].id
		}
		return keys[i] < keys[j]
	})

	so.writeCommentFmt("%s ID Constants", constType)
	for _, name := range keys {
		id := entries[name].id
		so.writeComment(name)
		so.language.writeConstUint32(so, id, name, constType, "id")
	}

	if so.options.isForTesting() {
		so.writeLine("")
		so.writeCommentFmt("Index into the list of %ss. Used to look up %ss in the registry proto directly.", constType, constType)
		for _, name := range keys {
			index := entries[name].index
			so.language.writeConstUint32(so, uint32(index), name, constType, "index")
		}
	}
	so.writeLine("")
}

type EnumName struct {
	prefix, suffix string
	addNameMap     bool
}

type EnumEntry struct {
	events  map[uint32]string
	aliases map[string]string
	names   []EnumName
}

// writeEnum prints out an enum with a for list of EventCodes (cobalt v1.0 only)
//
// It prints out the event_code string using toIdent, (event_code => EventCode).
// In c++ and Dart, it also creates a series of constants that effectively
// export the enum values. For a metric called "foo_bar" with a event named
// "baz", it would generate the constant:
// "FooBarEventCode_Baz = FooBarEventCode::Baz"
func (so *sourceOutputter) writeEnum(entry EnumEntry, projectName string, allEnums []EnumEntry) {
	if len(entry.events) == 0 {
		return
	}

	if len(entry.names) == 0 {
		return
	}

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

	hasGlobalName := so.language.supportsTypeAlias()
	firstSuffix := entry.names[0].suffix

	if so.language.supportsTypeAlias() {
		// Verify that all suffixes are the same for this entry
		for _, name := range entry.names {
			if name.suffix != firstSuffix {
				hasGlobalName = false
			}
		}

		// Verify that no other entry has this suffix
		for _, enum := range allEnums {
			if !reflect.DeepEqual(enum, entry) {
				for _, name := range enum.names {
					if name.suffix == firstSuffix {
						hasGlobalName = false
					}
				}
			}
		}
	}

	projectNamePrefix := projectName
	for _, name := range entry.names {
		if name.prefix == projectNamePrefix {
			projectNamePrefix = projectNamePrefix + " project"
		}
	}

	for i, name := range entry.names {
		if i == 0 || !so.language.supportsTypeAlias() {
			prefix := name.prefix
			if hasGlobalName {
				prefix = projectNamePrefix
			}

			if name.addNameMap {
				so.writeCommentFmt("String map for %s (%s)", prefix, name.suffix)
				so.language.writeConstMap(so, entry.events, name.prefix, name.suffix, "name map")
				so.writeLine("")
			}

			so.writeCommentFmt("Enum for %s (%s)", prefix, name.suffix)
			so.language.writeEnumBegin(so, prefix, name.suffix)
			for _, id := range keys {
				name := entry.events[id]
				so.language.writeEnumEntry(so, id, name)
			}
			if len(entry.aliases) > 0 {
				so.language.writeEnumAliasesBegin(so, prefix, name.suffix)
				for from, to := range entry.aliases {
					so.language.writeEnumAlias(so, []string{prefix, name.suffix}, []string{from}, []string{to})
				}
			}
			so.language.writeEnumEnd(so, prefix, name.suffix)
			if hasGlobalName {
				so.writeCommentFmt("Alias for %s (%s) which has the same event codes", name.prefix, name.suffix)
				so.language.writeTypeAlias(so, []string{prefix, name.suffix}, []string{name.prefix, name.suffix})
			}
		} else {
			first := entry.names[0]
			if hasGlobalName {
				first = EnumName{prefix: projectNamePrefix, suffix: first.suffix}
			}
			so.writeCommentFmt("Alias for %s (%s) which has the same event codes", name.prefix, name.suffix)
			so.language.writeTypeAlias(so, []string{first.prefix, first.suffix}, []string{name.prefix, name.suffix})

			if name.addNameMap {
				so.writeCommentFmt("String map for %s (%s)", name.prefix, name.suffix)
				so.language.writeConstMap(so, entry.events, name.prefix, name.suffix, "name map")
				so.writeLine("")
			}
		}

		for _, id := range keys {
			so.language.writeEnumExport(so, []string{name.prefix, name.suffix}, []string{entry.events[id]})
		}
		if len(entry.aliases) > 0 {
			for _, to := range entry.aliases {
				so.language.writeEnumExport(so, []string{name.prefix, name.suffix}, []string{to})
			}
		}
		so.writeLine("")
	}
}

func (so *sourceOutputter) Bytes() []byte {
	return so.buffer.Bytes()
}

func (so *sourceOutputter) writeIntBuckets(buckets *config.IntegerBuckets, name ...string) {
	linear := buckets.GetLinear()
	if linear != nil {
		so.writeCommentFmt("Linear bucket constants for %s", strings.Join(name, " "))
		name = append(name, "int buckets")
		so.language.writeConstInt64(so, linear.Floor, append(name, "floor")...)
		so.language.writeConstUint32(so, linear.NumBuckets, append(name, "num buckets")...)
		so.language.writeConstUint32(so, linear.StepSize, append(name, "step size")...)
		so.writeLine("")
	}

	exponential := buckets.GetExponential()
	if exponential != nil {
		so.writeCommentFmt("Exponential bucket constants for %s", strings.Join(name, " "))
		name = append(name, "int buckets")
		so.language.writeConstInt64(so, exponential.Floor, append(name, "floor")...)
		so.language.writeConstUint32(so, exponential.NumBuckets, append(name, "num buckets")...)
		so.language.writeConstUint32(so, exponential.InitialStep, append(name, "initial step")...)
		so.language.writeConstUint32(so, exponential.StepMultiplier, append(name, "step multiplier")...)
		so.writeLine("")
	}
}

func (so *sourceOutputter) writeV1Constants(c *config.CobaltRegistry) error {
	metrics := make(map[string]idEntry)
	var reports []map[string]idEntry
	if len(c.Customers) > 1 || len(c.Customers[0].Projects) > 1 {
		return fmt.Errorf("Cobalt v1.0 output can only be used with a single project registry.")
	}
	so.writeNames(c)
	so.writeLine("")
	for i, metric := range c.Customers[0].Projects[0].Metrics {
		if metric.MetricName != "" {
			so.writeIntBuckets(metric.GetIntBuckets(), metric.MetricName)

			metrics[metric.MetricName] = idEntry{id: metric.Id, index: i}
			metric_reports := make(map[string]idEntry)
			for j, report := range metric.Reports {
				if report.ReportName != "" {
					so.writeIntBuckets(report.GetIntBuckets(), metric.MetricName, report.ReportName)

					metric_reports[fmt.Sprintf("%s %s", metric.MetricName, report.ReportName)] = idEntry{id: report.Id, index: j}
				}
			}
			reports = append(reports, metric_reports)
		}
	}

	so.writeIdConstants("Metric", metrics)
	if so.options.isForTesting() {
		for _, metric_reports := range reports {
			so.writeIdConstants("Report", metric_reports)
		}
	}

	var enums []EnumEntry
	for _, metric := range c.Customers[0].Projects[0].Metrics {
		if len(metric.MetricDimensions) > 0 {
			for i, md := range metric.MetricDimensions {
				events := make(map[uint32]string)
				for value, name := range md.EventCodes {
					events[value] = name
				}
				varname := "Metric Dimension " + strconv.Itoa(i)
				if md.Dimension != "" {
					varname = "Metric Dimension " + md.Dimension
				}
				found := false
				for i, e := range enums {
					if reflect.DeepEqual(e.events, events) && reflect.DeepEqual(e.aliases, md.EventCodeAliases) {
						enums[i].names = append(enums[i].names, EnumName{prefix: metric.MetricName, suffix: varname, addNameMap: so.options.shouldGenerateNameMapsFor(metric.Id)})
						found = true
						break
					}
				}
				if !found {
					enums = append(enums, EnumEntry{
						events:  events,
						aliases: md.EventCodeAliases,
						names: []EnumName{
							{
								prefix:     metric.MetricName,
								suffix:     varname,
								addNameMap: so.options.shouldGenerateNameMapsFor(metric.Id),
							},
						},
					})
				}
			}
		}
	}

	for _, e := range enums {
		so.writeEnum(e, c.Customers[0].Projects[0].ProjectName, enums)
	}

	for _, metric := range c.Customers[0].Projects[0].Metrics {
		definedDimensions := 0
		for _, md := range metric.MetricDimensions {
			if len(md.EventCodes) > 0 {
				definedDimensions += 1
			}
		}

		// If there are 2 or more MetricDimensions, we will generate a helper struct for managing them.
		if definedDimensions > 1 && definedDimensions == len(metric.MetricDimensions) {
			so.language.writeStructBegin(so, metric.MetricName, "event codes")
			fields := [][]string{}
			for i, md := range metric.MetricDimensions {
				if len(md.EventCodes) > 0 {
					name := "Dimension " + strconv.Itoa(i)
					varname := "Metric Dimension " + strconv.Itoa(i)
					if md.Dimension != "" {
						name = md.Dimension
						varname = "Metric Dimension " + md.Dimension
					}
					fields = append(fields, []string{name})
					so.language.writeStructField(so, []string{name}, []string{metric.MetricName, varname})
				}
			}
			so.language.writeToVectorMethod(so, []string{metric.MetricName, "event codes"}, fields)
			so.language.writeStructEnd(so)
			so.writeLine("")
		}
	}

	return nil
}

func (so *sourceOutputter) writeNames(c *config.CobaltRegistry) {
	so.language.writeStringConstant(so, c.Customers[0].CustomerName, "Customer Name")
	so.language.writeConstUint32(so, c.Customers[0].CustomerId, "Customer Id")
	so.language.writeStringConstant(so, c.Customers[0].Projects[0].ProjectName, "Project Name")
	so.language.writeConstUint32(so, c.Customers[0].Projects[0].ProjectId, "Project Id")
}

func (so *sourceOutputter) writeFile(c, filtered *config.CobaltRegistry) error {
	so.writeGenerationWarning()

	customer := ""
	project := ""

	for _, cust := range c.Customers {
		customer = strings.TrimLeft(customer+"_"+cust.CustomerName, "_")
		for _, proj := range cust.Projects {
			project = strings.TrimLeft(project+"_"+proj.ProjectName, "_")
		}
	}

	so.language.writeExtraHeader(so, customer, project, so.namespaces)
	so.language.writeNamespacesBegin(so, so.namespaces, so.outFilename)

	if len(c.Customers) == 1 && len(c.Customers[0].Projects) == 1 {
		if err := so.writeV1Constants(c); err != nil {
			return err
		}
	}

	b64Bytes, err := Base64Output(c, filtered)
	if err != nil {
		return err
	}

	if so.options.shouldGenerateConfigBase64() {
		so.writeComment("The base64 encoding of the bytes of a serialized CobaltRegistry proto message.")
		so.language.writeStringConstant(so, string(b64Bytes), so.varName)
	}

	so.language.writeNamespacesEnd(so, so.namespaces, so.outFilename)
	so.language.writeExtraFooter(so, customer, project, so.namespaces)

	return nil
}

func (so *sourceOutputter) getOutputFormatter() OutputFormatter {
	return func(c, filtered *config.CobaltRegistry) (outputBytes []byte, err error) {
		err = so.writeFile(c, filtered)
		return so.Bytes(), err
	}
}

func getOutputFormatter(format, namespace, goPackageName, varName string, options generatorOptions, outFilename string, errorCalculator *privacy.ErrorCalculator) (OutputFormatter, error) {
	namespaceList := []string{}
	if namespace != "" {
		namespaceList = strings.Split(namespace, ".")
	}
	switch format {
	case "bin":
		return BinaryOutput, nil
	case "b64":
		return Base64Output, nil
	case "cpp":
		return CppOutputFactory(varName, namespaceList, options), nil
	case "dart":
		return DartOutputFactory(varName, options), nil
	case "go":
		if goPackageName == "" {
			return nil, fmt.Errorf("no package name specified for go output formatter")
		}
		return GoOutputFactory(varName, goPackageName, options), nil
	case "java":
		return JavaOutputFactory(varName, namespaceList, options, outFilename), nil
	case "json":
		return JSONOutputFactory(), nil
	case "rust":
		return RustOutputFactory(varName, namespaceList, options), nil
	default:
		return nil, fmt.Errorf("'%v' is an invalid out_format parameter. 'bin', 'b64', 'cpp', 'dart', 'go', 'java', 'rust', and 'json' are the only valid values for out_format.", format)
	}
}
