// 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)
	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 generatorFeatures struct {
	enabledFeatures map[string]bool
}

func newGeneratorFeatures(features []string) generatorFeatures {
	enabledFeatures := map[string]bool{}
	for _, feature := range features {
		enabledFeatures[feature] = true
	}

	return generatorFeatures{enabledFeatures: enabledFeatures}
}

func (f *generatorFeatures) isForTesting() bool {
	return f.enabledFeatures["testing"]
}

func (f *generatorFeatures) shouldGenerateConfigBase64() bool {
	return f.enabledFeatures["generate-config-base64"]
}

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

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

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

func newSourceOutputterWithNamespacesAndFilename(language outputLanguage, varName string, namespaces []string, features []string, outFilename string) *sourceOutputter {
	return &sourceOutputter{
		buffer:      new(bytes.Buffer),
		language:    language,
		varName:     varName,
		namespaces:  namespaces,
		features:    newGeneratorFeatures(features),
		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.features.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
}

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 i, name := range entry.names {
		if i == 0 || !so.language.supportsTypeAlias() {
			prefix := name.prefix
			if hasGlobalName {
				prefix = projectNamePrefix
			}
			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})
		}

		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.features.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})
						found = true
						break
					}
				}
				if !found {
					enums = append(enums, EnumEntry{
						events:  events,
						aliases: md.EventCodeAliases,
						names: []EnumName{
							{
								prefix: metric.MetricName,
								suffix: varname,
							},
						},
					})
				}
			}
		}
	}

	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.features.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, features []string, 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, features), nil
	case "dart":
		return DartOutputFactory(varName, features), nil
	case "go":
		if goPackageName == "" {
			return nil, fmt.Errorf("no package name specified for go output formatter")
		}
		return GoOutputFactory(varName, goPackageName, features), nil
	case "java":
		return JavaOutputFactory(varName, namespaceList, features, outFilename), nil
	case "json":
		return JSONOutputFactory(errorCalculator), nil
	case "rust":
		return RustOutputFactory(varName, namespaceList, features), 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)
	}
}
