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

package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"text/template"

	"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

var primitiveTypes = map[fidlgen.PrimitiveSubtype]string{
	fidlgen.Bool:    "bool",
	fidlgen.Int8:    "int8_t",
	fidlgen.Int16:   "int16_t",
	fidlgen.Int32:   "int32_t",
	fidlgen.Int64:   "int64_t",
	fidlgen.Uint8:   "uint8_t",
	fidlgen.Uint16:  "uint16_t",
	fidlgen.Uint32:  "uint32_t",
	fidlgen.Uint64:  "uint64_t",
	fidlgen.Float32: "float",
	fidlgen.Float64: "double",
}

func mustReadJSONIr(filename string) fidlgen.Root {
	root, err := fidlgen.ReadJSONIr(filename)
	if err != nil {
		log.Fatal(err)
	}
	return root
}

func main() {
	cmdlineflags := GetFlags()
	options := make(Options)
	flag.Var(&options, "options",
		"comma-separated list if name=value pairs.")
	flag.Parse()

	if !cmdlineflags.Valid() {
		flag.PrintDefaults()
		os.Exit(1)
	}

	results := GenerateFidl(*cmdlineflags.templatePath,
		cmdlineflags.FidlAmendments().Amend(mustReadJSONIr(*cmdlineflags.jsonPath)),
		cmdlineflags.outputBase,
		options)

	if results != nil {
		log.Printf("Error running generator: %v", results)
		os.Exit(1)
	}
}

// Amendments to be applied to a fidl.Root
type Amendments struct {
	ExcludedDecls []fidlgen.EncodedCompoundIdentifier `json:"exclusions,omitempty"`
}

func (a Amendments) Amend(root fidlgen.Root) fidlgen.Root {
	return a.ApplyExclusions(root)
}

func (a Amendments) ApplyExclusions(root fidlgen.Root) fidlgen.Root {
	if len(a.ExcludedDecls) == 0 {
		return root
	}

	excludeMap := make(map[fidlgen.EncodedCompoundIdentifier]struct{})
	for _, excludedDecl := range a.ExcludedDecls {
		excludeMap[excludedDecl] = struct{}{}
		delete(root.Decls, excludedDecl)
	}

	newConsts := root.Consts[:0]
	for _, element := range root.Consts {
		_, found := excludeMap[element.Name]
		if !found {
			newConsts = append(newConsts, element)
		}
	}
	root.Consts = newConsts

	newEnums := root.Enums[:0]
	for _, element := range root.Enums {
		_, found := excludeMap[element.Name]
		if !found {
			newEnums = append(newEnums, element)
		}
	}
	root.Enums = newEnums

	newProtocols := root.Protocols[:0]
	for _, element := range root.Protocols {
		_, found := excludeMap[element.Name]
		if !found {
			newProtocols = append(newProtocols, element)
		}
	}
	root.Protocols = newProtocols

	newStructs := root.Structs[:0]
	for _, element := range root.Structs {
		_, found := excludeMap[element.Name]
		if !found {
			newStructs = append(newStructs, element)
		}
	}
	root.Structs = newStructs

	newTables := root.Tables[:0]
	for _, element := range root.Tables {
		_, found := excludeMap[element.Name]
		if !found {
			newTables = append(newTables, element)
		}
	}
	root.Tables = newTables

	newUnions := root.Unions[:0]
	for _, element := range root.Unions {
		_, found := excludeMap[element.Name]
		if !found {
			newUnions = append(newUnions, element)
		}
	}
	root.Unions = newUnions

	newDeclOrder := root.DeclOrder[:0]
	for _, element := range root.DeclOrder {
		_, found := excludeMap[element]
		if !found {
			newDeclOrder = append(newDeclOrder, element)
		}
	}
	root.DeclOrder = newDeclOrder

	return root
}

// Root struct passed as the initial 'dot' for the template.
type Root struct {
	fidlgen.Root
	OutputBase      string
	templates       *template.Template
	options         Options
	constsByName    map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Const
	enumsByName     map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Enum
	protocolsByName map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Protocol
	structsByName   map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Struct
	tablesByName    map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Table
	unionsByName    map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Union
	librariesByName map[fidlgen.EncodedLibraryIdentifier]*fidlgen.Library
}

func NewRoot(ir fidlgen.Root, outputBase string, templates *template.Template, options Options) *Root {
	// Do a first pass of the protocols, creating a set of all names of types that are used as a
	// transactional message bodies.
	mbtn := ir.GetMessageBodyTypeNames()

	constsByName := make(map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Const)
	for index, member := range ir.Consts {
		constsByName[member.Name] = &ir.Consts[index]
	}

	enumsByName := make(map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Enum)
	for index, member := range ir.Enums {
		enumsByName[member.Name] = &ir.Enums[index]
	}

	protocolsByName := make(map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Protocol)
	for index, member := range ir.Protocols {
		protocolsByName[member.Name] = &ir.Protocols[index]
	}

	// Store all structs in structsByName so that getParams can access them.
	structsByName := make(map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Struct)
	for index, member := range ir.Structs {
		structsByName[member.Name] = &ir.Structs[index]
	}

	// But filter out anonymous message body structs in ir.Structs so that
	// templates that range over ir.Structs don't include them.
	allStructs := ir.Structs
	ir.Structs = nil
	for _, member := range allStructs {
		if _, ok := mbtn[member.Name]; ok && member.IsAnonymous() {
			continue
		}
		ir.Structs = append(ir.Structs, member)
	}

	tablesByName := make(map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Table)
	for index, member := range ir.Tables {
		tablesByName[member.Name] = &ir.Tables[index]
	}

	unionsByName := make(map[fidlgen.EncodedCompoundIdentifier]*fidlgen.Union)
	for index, member := range ir.Unions {
		unionsByName[member.Name] = &ir.Unions[index]
	}

	librariesByName := make(map[fidlgen.EncodedLibraryIdentifier]*fidlgen.Library)
	for index, member := range ir.Libraries {
		librariesByName[member.Name] = &ir.Libraries[index]
	}

	return &Root{
		ir,
		outputBase,
		templates,
		options,
		constsByName,
		enumsByName,
		protocolsByName,
		structsByName,
		tablesByName,
		unionsByName,
		librariesByName,
	}
}

// Applies the specified template to the specified data and writes the output
// to outputPath.
func (root Root) Generate(outputPath string, template string, data interface{}) (string, error) {
	if err := os.MkdirAll(filepath.Dir(outputPath), os.ModePerm); err != nil {
		return "", err
	}

	f, err := os.Create(outputPath)
	if err != nil {
		return "", err
	}
	defer f.Close()

	err = root.templates.ExecuteTemplate(f, template, data)
	if err != nil {
		return "", err
	}

	return "", nil
}

// Returns an output file path with the specified extension.
func (root Root) Output(ext string) string {
	return root.OutputBase + ext
}

// Gets a constant by name.
func (root Root) GetConst(name fidlgen.EncodedCompoundIdentifier) *fidlgen.Const {
	return root.constsByName[name]
}

// Gets an enum by name.
func (root Root) GetEnum(name fidlgen.EncodedCompoundIdentifier) *fidlgen.Enum {
	return root.enumsByName[name]
}

// Gets a protocol by name.
func (root Root) GetProtocol(name fidlgen.EncodedCompoundIdentifier) *fidlgen.Protocol {
	return root.protocolsByName[name]
}

// Gets a struct by name.
func (root Root) GetStruct(name fidlgen.EncodedCompoundIdentifier) *fidlgen.Struct {
	return root.structsByName[name]
}

// Gets a struct by name.
func (root Root) GetTable(name fidlgen.EncodedCompoundIdentifier) *fidlgen.Table {
	return root.tablesByName[name]
}

// Gets a union by name.
func (root Root) GetUnion(name fidlgen.EncodedCompoundIdentifier) *fidlgen.Union {
	return root.unionsByName[name]
}

// Gets a library by name.
func (root Root) GetLibrary(name fidlgen.EncodedLibraryIdentifier) *fidlgen.Library {
	return root.librariesByName[name]
}

// Generates code using the specified template.
func GenerateFidl(templatePath string, ir fidlgen.Root, outputBase *string, options Options) error {
	returnBytes, err := os.ReadFile(templatePath)
	if err != nil {
		log.Fatalf("Error reading from %s: %v", templatePath, err)
	}

	tmpls := template.New("tmpls")

	root := NewRoot(ir, *outputBase, tmpls, options)

	funcMap := template.FuncMap{
		// Gets the decltype for an EncodedCompoundIdentifier.
		"declType": func(eci fidlgen.EncodedCompoundIdentifier) fidlgen.DeclType {
			if root.Name == eci.LibraryName() {
				return root.Decls[eci]
			}
			library := root.GetLibrary(eci.LibraryName())
			return library.Decls[eci].Type
		},
		// Determines if an EncodedCompoundIdentifier refers to a local definition.
		"isLocal": func(eci fidlgen.EncodedCompoundIdentifier) bool {
			return root.Name == eci.LibraryName()
		},
		// Converts an identifier to snake case.
		"toSnakeCase": func(id fidlgen.Identifier) string {
			return fidlgen.ToSnakeCase(string(id))
		},
		// Converts an identifier to upper camel case.
		"toUpperCamelCase": func(id fidlgen.Identifier) string {
			return fidlgen.ToUpperCamelCase(string(id))
		},
		// Converts an identifier to lower camel case.
		"toLowerCamelCase": func(id fidlgen.Identifier) string {
			return fidlgen.ToLowerCamelCase(string(id))
		},
		// Converts an identifier to friendly case.
		"toFriendlyCase": func(id fidlgen.Identifier) string {
			return fidlgen.ToFriendlyCase(string(id))
		},
		// Removes a leading 'k' from an identifier.
		"removeLeadingK": func(id fidlgen.Identifier) string {
			return fidlgen.RemoveLeadingK(string(id))
		},
		// Gets an option value (as a string) by name.
		"getOption": func(name string) string {
			return root.options[name]
		},
		// Gets an option (as an Identifier) by name.
		"getOptionAsIdentifier": func(name string) fidlgen.Identifier {
			return fidlgen.Identifier(root.options[name])
		},
		// Gets an option (as an EncodedLibraryIdentifier) by name.
		"getOptionAsEncodedLibraryIdentifier": func(name string) fidlgen.EncodedLibraryIdentifier {
			return fidlgen.EncodedLibraryIdentifier(root.options[name])
		},
		// Gets an option (as an EncodedCompoundIdentifier) by name.
		"getOptionAsEncodedCompoundIdentifier": func(name string) fidlgen.EncodedCompoundIdentifier {
			return fidlgen.EncodedCompoundIdentifier(root.options[name])
		},
		// Returns the template executed
		"execTmpl": func(template string, data interface{}) (string, error) {
			buffer := &bytes.Buffer{}
			err = root.templates.ExecuteTemplate(buffer, template, data)
			return buffer.String(), err
		},
		// Determines if a protocol is discoverable.
		"isDiscoverable": func(i fidlgen.Protocol) bool {
			return i.HasAttribute("discoverable")
		},
		// Determines if a method is transitional.
		"isTransitional": func(m fidlgen.Method) bool {
			return m.HasAttribute("transitional")
		},
		// Converts a primitive subtype to its C equivalent.
		"toCType": func(p fidlgen.PrimitiveSubtype) string {
			return primitiveTypes[p]
		},
		// Gets a flat list of parameters for a request/response payload.
		"getParams": func(t *fidlgen.Type) []fidlgen.StructMember {
			if t == nil {
				return nil
			}
			if t.Kind != fidlgen.IdentifierType {
				panic(fmt.Sprintf("expected IdentifierType, got %s", t.Kind))
			}
			if s, ok := root.structsByName[t.Identifier]; ok {
				return s.Members
			}
			panic(fmt.Sprintf("%s: fidlmerge only supports struct requests/responses", t.Identifier))
		},
	}

	template.Must(tmpls.Funcs(funcMap).Parse(string(returnBytes[:])))

	err = tmpls.ExecuteTemplate(os.Stdout, "Main", root)
	if err != nil {
		return err
	}

	return nil
}
