// 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.

package hlcpp

import (
	"bytes"
	"fmt"
	"regexp"
	"sort"
	"strings"
	"text/template"

	"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
	"go.fuchsia.dev/fuchsia/tools/fidl/measure-tape/src/measurer"
	"go.fuchsia.dev/fuchsia/tools/fidl/measure-tape/src/utils"
)

type Printer struct {
	m            *measurer.Measurer
	hIncludePath string
}

func NewPrinter(m *measurer.Measurer, hIncludePath string) *Printer {
	return &Printer{
		m:            m,
		hIncludePath: hIncludePath,
	}
}

type tmplParams struct {
	Year                   string
	HeaderTag              string
	HIncludePath           string
	Namespaces             []string
	LibraryNameWithSlashes string
	TargetTypes            []string
	CcIncludes             []string
}

func (params tmplParams) RevNamespaces() []string {
	rev := make([]string, len(params.Namespaces), len(params.Namespaces))
	for i, j := 0, len(params.Namespaces)-1; i < len(params.Namespaces); i, j = i+1, j-1 {
		rev[i] = params.Namespaces[j]
	}
	return rev
}

var header = template.Must(template.New("tmpls").Parse(`// Copyright {{ .Year }} 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.

// Code generated by "measure-tape"; DO NOT EDIT.
//
// See tools/fidl/measure-tape/README.md

#ifndef {{ .HeaderTag }}
#define {{ .HeaderTag }}

#include <{{ .LibraryNameWithSlashes }}/cpp/fidl.h>

{{ range .Namespaces }}
namespace {{ . }} {
{{- end}}

struct Size {
  explicit Size(int64_t num_bytes, int64_t num_handles)
    : num_bytes(num_bytes), num_handles(num_handles) {}

  const int64_t num_bytes;
  const int64_t num_handles;
};

{{ range $targetType := .TargetTypes }}
// Helper function to measure {{ $targetType }}.
//
// In most cases, the size returned is a precise size. Otherwise, the size
// returned is a safe upper-bound.
Size Measure(const {{ $targetType }}& value);
{{ end }}

{{ range .RevNamespaces }}
}  // {{ . }}
{{- end}}

#endif  // {{ .HeaderTag }}
`))

var ccTop = template.Must(template.New("tmpls").Parse(`// Copyright {{ .Year }} 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.

// Code generated by "measure-tape"; DO NOT EDIT.
//
// See tools/fidl/measure-tape/README.md

#include <{{ .HIncludePath }}>
{{ range .CcIncludes }}
{{ . }}
{{- end }}
#include <zircon/types.h>

{{ range .Namespaces }}
namespace {{ . }} {
{{- end}}

namespace {

class MeasuringTape {
 public:
  MeasuringTape() = default;
`))

var ccBottom = template.Must(template.New("tmpls").Parse(`
  Size Done() {
    if (maxed_out_) {
      return Size(ZX_CHANNEL_MAX_MSG_BYTES, ZX_CHANNEL_MAX_MSG_HANDLES);
    }
    return Size(num_bytes_, num_handles_);
  }

private:
  void MaxOut() { maxed_out_ = true; }

  bool maxed_out_ = false;
  int64_t num_bytes_ = 0;
  int64_t num_handles_ = 0;
};

}  // namespace

{{ range $targetType := .TargetTypes }}
Size Measure(const {{ $targetType }}& value) {
  MeasuringTape tape;
  tape.Measure(value);
  return tape.Done();
}
{{ end }}

{{ range .RevNamespaces }}
}  // {{ . }}
{{- end}}
`))

var pathSeparators = regexp.MustCompile("[/_.-]")

func (p *Printer) newTmplParams(targetMts []*measurer.MeasuringTape) tmplParams {
	libraryName := targetMts[0].Name().LibraryName()
	for _, targetMt := range targetMts[1:] {
		if otherLibraryName := targetMt.Name().LibraryName(); libraryName != otherLibraryName {
			panic(fmt.Sprintf("all target types must be in the same library, found %s and %s", libraryName, otherLibraryName))
		}
	}
	namespaces := []string{"measure_tape"}
	namespaces = append(namespaces, libraryName.Parts()...)

	headerTagParts := pathSeparators.Split(p.hIncludePath, -1)
	for i, part := range headerTagParts {
		headerTagParts[i] = strings.ToUpper(part)
	}
	headerTagParts = append(headerTagParts, "")
	headerTag := strings.Join(headerTagParts, "_")

	var targetMtsNames []string
	for _, targetMt := range targetMts {
		targetMtsNames = append(targetMtsNames, fmtType(targetMt.Name()))
	}
	return tmplParams{
		Year:                   "2020",
		HeaderTag:              headerTag,
		HIncludePath:           p.hIncludePath,
		LibraryNameWithSlashes: strings.Join(libraryName.Parts(), "/"),
		TargetTypes:            targetMtsNames,
		Namespaces:             namespaces,
	}
}

func (p *Printer) WriteH(buf *bytes.Buffer, targetMts []*measurer.MeasuringTape) {
	if err := header.Execute(buf, p.newTmplParams(targetMts)); err != nil {
		panic(err)
	}
}

func (p *Printer) WriteCc(buf *bytes.Buffer,
	targetMts []*measurer.MeasuringTape,
	allMethods map[measurer.MethodID]*measurer.Method) {

	params := p.newTmplParams(targetMts)
	for _, libraryName := range p.m.RootLibraries() {
		params.CcIncludes = append(params.CcIncludes,
			fmt.Sprintf("#include <%s/cpp/fidl.h>", strings.Join(libraryName.Parts(), "/")))
	}
	sort.Strings(params.CcIncludes)

	if err := ccTop.Execute(buf, params); err != nil {
		panic(err)
	}

	cb := codeBuffer{buf: buf, level: 1}
	utils.ForAllMethodsInOrder(allMethods, func(m *measurer.Method) {
		buf.WriteString("\n")
		cb.writeMethod(m)
	})

	if err := ccBottom.Execute(buf, params); err != nil {
		panic(err)
	}
}

const indent = "  "

type codeBuffer struct {
	level int
	buf   *bytes.Buffer
}

func (buf *codeBuffer) writef(format string, a ...interface{}) {
	for i := 0; i < buf.level; i++ {
		buf.buf.WriteString(indent)
	}
	buf.buf.WriteString(fmt.Sprintf(format, a...))
}

func (buf *codeBuffer) indent(fn func()) {
	buf.level++
	fn()
	buf.level--
}

var _ measurer.StatementFormatter = (*codeBuffer)(nil)

func (buf *codeBuffer) CaseMaxOut() {
	buf.writef("MaxOut();\n")
}

func (buf *codeBuffer) CaseAddNumBytes(val measurer.Expression) {
	buf.writef("num_bytes_ += %s;\n", formatExpr{val}.String())
}

func (buf *codeBuffer) CaseAddNumHandles(val measurer.Expression) {
	buf.writef("num_handles_ += %s;\n", formatExpr{val}.String())
}

func (buf *codeBuffer) CaseInvoke(id measurer.MethodID, val measurer.Expression) {
	buf.writef("%s(%s);\n", fmtMethodKind(id.Kind), formatExpr{val}.String())
}

func (buf *codeBuffer) CaseGuard(cond measurer.Expression, body *measurer.Block) {
	buf.writef("if (%s) {\n", formatExpr{cond}.String())
	buf.indent(func() {
		buf.writeBlock(body)
	})
	buf.writef("}\n")
}

func (buf *codeBuffer) CaseIterate(local, val measurer.Expression, body *measurer.Block) {
	var deref string
	if val.Nullable() {
		deref = "*"
	}
	buf.writef("for (const auto& %s : %s%s) {\n",
		formatExpr{local}.String(),
		deref, formatExpr{val}.String())
	buf.indent(func() {
		buf.writeBlock(body)
	})
	buf.writef("}\n")
}

func (buf *codeBuffer) CaseSelectVariant(
	val measurer.Expression,
	targetType fidlgen.Name,
	variants map[string]measurer.LocalWithBlock) {

	buf.writef("switch (%s.Which()) {\n", formatExpr{val}.String())
	buf.indent(func() {
		utils.ForAllVariantsInOrder(variants, func(member string, localWithBlock measurer.LocalWithBlock) {
			if member != measurer.UnknownVariant {
				buf.writef("case %s: {\n", fmtKnownVariant(targetType, member))
			} else {
				buf.writef("case %s: {\n", fmtUnknownVariant(targetType))
			}
			buf.indent(func() {
				if local := localWithBlock.Local; local != nil {
					// TODO(fxbug.dev/51366): Improve local vars handling.
					buf.writef("__attribute__((unused)) auto const& %s = %s.%s();\n",
						formatExpr{local},
						formatExpr{val}, fidlgen.ToSnakeCase(member))
				}
				buf.writeBlock(localWithBlock.Body)
				buf.writef("break;\n")
			})
			buf.writef("}\n")
		})

		// In addition to all the member variants, we need to emit special
		// handling for uninitialized unions which are marked as 'invalid'.
		buf.writef("case %s: {\n", fmtInvalidVariant(targetType))
		buf.indent(func() {
			buf.writef("MaxOut();\n")
			buf.writef("break;\n")
		})
		buf.writef("}\n")
	})
	buf.writef("}\n")
}

func (buf *codeBuffer) CaseDeclareMaxOrdinal(local measurer.Expression) {
	buf.writef("int32_t %s = 0;\n", formatExpr{local}.String())
}

func (buf *codeBuffer) CaseSetMaxOrdinal(local, ordinal measurer.Expression) {
	buf.writef("%s = %s;\n", formatExpr{local}.String(), formatExpr{ordinal}.String())
}

func (buf *codeBuffer) writeBlock(b *measurer.Block) {
	b.ForAllStatements(func(stmt *measurer.Statement) {
		stmt.Visit(buf)
	})
}

func (buf *codeBuffer) writeMethod(m *measurer.Method) {
	buf.writef("void %s(const %s& %s) {\n", fmtMethodKind(m.ID.Kind), fmtType(m.ID.TargetType), formatExpr{m.Arg})
	buf.indent(func() {
		buf.writeBlock(m.Body)
	})
	buf.writef("}\n")
}

func fmtMethodKind(kind measurer.MethodKind) string {
	switch kind {
	case measurer.Measure:
		return "Measure"
	case measurer.MeasureOutOfLine:
		return "MeasureOutOfLine"
	case measurer.MeasureHandles:
		return "MeasureHandles"
	default:
		panic(fmt.Sprintf("should not be reachable for method kind %v", kind))
	}
}

func fmtType(name fidlgen.Name) string {
	return fmt.Sprintf("::%s::%s", strings.Join(name.LibraryName().Parts(), "::"), name.DeclarationName())
}

func fmtKnownVariant(name fidlgen.Name, variant string) string {
	return fmt.Sprintf("%s::Tag::k%s", fmtType(name), fidlgen.ToUpperCamelCase(variant))
}

func fmtUnknownVariant(name fidlgen.Name) string {
	return fmt.Sprintf("%s::Tag::kUnknown", fmtType(name))
}

func fmtInvalidVariant(name fidlgen.Name) string {
	return fmt.Sprintf("%s::Tag::Invalid", fmtType(name))
}

type formatExpr struct {
	measurer.Expression
}

func (val formatExpr) String() string {
	return val.Fmt(val)
}

var _ measurer.ExpressionFormatter = formatExpr{}

func (formatExpr) CaseNum(num int) string {
	return fmt.Sprintf("%d", num)
}

func (formatExpr) CaseLocal(name string, _ measurer.TapeKind) string {
	return name
}

func (formatExpr) CaseMemberOf(val measurer.Expression, member string, _ measurer.TapeKind, _ bool) string {
	var accessor string
	if kind := val.AssertKind(measurer.Struct, measurer.Union, measurer.Table); kind != measurer.Struct {
		accessor = "()"
	}
	return fmt.Sprintf("%s%s%s%s", formatExpr{val}, getDerefOp(val), fidlgen.ToSnakeCase(member), accessor)
}

func (formatExpr) CaseFidlAlign(val measurer.Expression) string {
	return fmt.Sprintf("FIDL_ALIGN(%s)", formatExpr{val})
}

func (formatExpr) CaseLength(val measurer.Expression) string {
	var op string
	switch val.AssertKind(measurer.String, measurer.Vector) {
	case measurer.String:
		op = "length"
	case measurer.Vector:
		op = "size"
	}
	return fmt.Sprintf("%s%s%s()", formatExpr{val}, getDerefOp(val), op)
}

func (formatExpr) CaseHasMember(val measurer.Expression, member string) string {
	return fmt.Sprintf("%s%shas_%s()", formatExpr{val}, getDerefOp(val), fidlgen.ToSnakeCase(member))
}

func (formatExpr) CaseMult(lhs, rhs measurer.Expression) string {
	return fmt.Sprintf("%s * %s", formatExpr{lhs}, formatExpr{rhs})
}

func getDerefOp(val measurer.Expression) string {
	if val.Nullable() {
		return "->"
	}
	return "."
}
