// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// gen parses the <tint>/src/tint/intrinsics.def file, then scans the
// project directory for '<file>.tmpl' files, to produce source code files.
package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"text/template"
	"time"
	"unicode"

	"dawn.googlesource.com/dawn/tools/src/container"
	"dawn.googlesource.com/dawn/tools/src/fileutils"
	"dawn.googlesource.com/dawn/tools/src/glob"
	"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/gen"
	"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/parser"
	"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/resolver"
	"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/sem"
)

const defProjectRelPath = "src/tint/intrinsics.def"

func main() {
	if err := run(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func showUsage() {
	fmt.Println(`
gen generates the templated code for the Tint compiler

gen accepts a list of file paths to the templates to generate. If no templates
are explicitly specified, then gen scans the '<dawn>/src/tint' and
'<dawn>/test/tint' directories for '<file>.tmpl' files.

If the templates use the 'IntrinsicTable' function then gen will parse and
resolve the <tint>/src/tint/intrinsics.def file.

usage:
  gen [flags] [template files]

optional flags:`)
	flag.PrintDefaults()
	fmt.Println(``)
	os.Exit(1)
}

func run() error {
	outputDir := ""
	verbose := false
	flag.StringVar(&outputDir, "o", "", "custom output directory (optional)")
	flag.BoolVar(&verbose, "verbose", false, "print verbose output")
	flag.Parse()

	projectRoot := fileutils.DawnRoot()

	// Find clang-format
	clangFormatPath := findClangFormat(projectRoot)
	if clangFormatPath == "" {
		return fmt.Errorf("cannot find clang-format in <dawn>/buildtools nor PATH")
	}

	files := flag.Args()
	if len(files) == 0 {
		// Recursively find all the template files in the <dawn>/src/tint and
		// <dawn>/test/tint and directories
		var err error
		files, err = glob.Scan(projectRoot, glob.MustParseConfig(`{
			"paths": [{"include": [
				"src/tint/**.tmpl",
				"test/tint/**.tmpl"
			]}]
		}`))
		if err != nil {
			return err
		}
	} else {
		// Make all template file paths project-relative
		for i, f := range files {
			abs, err := filepath.Abs(f)
			if err != nil {
				return fmt.Errorf("failed to get absolute file path for '%v': %w", f, err)
			}
			if !strings.HasPrefix(abs, projectRoot) {
				return fmt.Errorf("template '%v' is not under project root '%v'", abs, projectRoot)
			}
			rel, err := filepath.Rel(projectRoot, abs)
			if err != nil {
				return fmt.Errorf("failed to get project relative file path for '%v': %w", f, err)
			}
			files[i] = rel
		}
	}

	cache := &genCache{}

	// For each template file...
	for _, relTmplPath := range files { // relative to project root
		if verbose {
			fmt.Println("processing", relTmplPath)
		}
		// Make tmplPath absolute
		tmplPath := filepath.Join(projectRoot, relTmplPath)
		tmplDir := filepath.Dir(tmplPath)

		// Read the template file
		tmpl, err := ioutil.ReadFile(tmplPath)
		if err != nil {
			return fmt.Errorf("failed to open '%v': %w", tmplPath, err)
		}

		// Create or update the file at relPath if the file content has changed,
		// preserving the copyright year in the header.
		// relPath is a path relative to the template
		writeFile := func(relPath, body string) error {
			var outPath string
			if outputDir != "" {
				relTmplDir := filepath.Dir(relTmplPath)
				outPath = filepath.Join(outputDir, relTmplDir, relPath)
			} else {
				outPath = filepath.Join(tmplDir, relPath)
			}

			copyrightYear := time.Now().Year()

			// Load the old file
			existing, err := ioutil.ReadFile(outPath)
			if err == nil {
				// Look for the existing copyright year
				if match := copyrightRegex.FindStringSubmatch(string(existing)); len(match) == 2 {
					if year, err := strconv.Atoi(match[1]); err == nil {
						copyrightYear = year
					}
				}
			}

			// Write the common file header
			if verbose {
				fmt.Println("  writing", outPath)
			}
			sb := strings.Builder{}
			sb.WriteString(fmt.Sprintf(header, copyrightYear, filepath.ToSlash(relTmplPath)))
			sb.WriteString(body)
			content := sb.String()
			return writeFileIfChanged(outPath, content, string(existing))
		}

		// Write the content generated using the template and semantic info
		sb := strings.Builder{}
		if err := generate(string(tmpl), cache, &sb, writeFile); err != nil {
			return fmt.Errorf("while processing '%v': %w", tmplPath, err)
		}

		if body := sb.String(); body != "" {
			_, tmplFileName := filepath.Split(tmplPath)
			outFileName := strings.TrimSuffix(tmplFileName, ".tmpl")

			switch filepath.Ext(outFileName) {
			case ".cc", ".h", ".inl":
				body, err = clangFormat(body, clangFormatPath)
				if err != nil {
					return err
				}
			}

			if err := writeFile(outFileName, body); err != nil {
				return err
			}
		}
	}

	return nil
}

// Cache for objects that are expensive to build, and can be reused between templates.
type genCache struct {
	cached struct {
		sem            *sem.Sem            // lazily built by sem()
		intrinsicTable *gen.IntrinsicTable // lazily built by intrinsicTable()
		permuter       *gen.Permuter       // lazily built by permute()
	}
}

// sem lazily parses and resolves the intrinsic.def file, returning the semantic info.
func (g *genCache) sem() (*sem.Sem, error) {
	if g.cached.sem == nil {
		// Load the builtins definition file
		defPath := filepath.Join(fileutils.DawnRoot(), defProjectRelPath)

		defSource, err := ioutil.ReadFile(defPath)
		if err != nil {
			return nil, err
		}

		// Parse the definition file to produce an AST
		ast, err := parser.Parse(string(defSource), defProjectRelPath)
		if err != nil {
			return nil, err
		}

		// Resolve the AST to produce the semantic info
		sem, err := resolver.Resolve(ast)
		if err != nil {
			return nil, err
		}

		g.cached.sem = sem
	}
	return g.cached.sem, nil
}

// intrinsicTable lazily calls and returns the result of buildIntrinsicTable(),
// caching the result for repeated calls.
func (g *genCache) intrinsicTable() (*gen.IntrinsicTable, error) {
	if g.cached.intrinsicTable == nil {
		sem, err := g.sem()
		if err != nil {
			return nil, err
		}
		g.cached.intrinsicTable, err = gen.BuildIntrinsicTable(sem)
		if err != nil {
			return nil, err
		}
	}
	return g.cached.intrinsicTable, nil
}

// permute lazily calls buildPermuter(), caching the result for repeated
// calls, then passes the argument to Permutator.Permute()
func (g *genCache) permute(overload *sem.Overload) ([]gen.Permutation, error) {
	if g.cached.permuter == nil {
		sem, err := g.sem()
		if err != nil {
			return nil, err
		}
		g.cached.permuter, err = gen.NewPermuter(sem)
		if err != nil {
			return nil, err
		}
	}
	return g.cached.permuter.Permute(overload)
}

// writes content to path if the file has changed
func writeFileIfChanged(path, newContent, oldContent string) error {
	if oldContent == newContent {
		return nil // Not changed
	}
	if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
		return fmt.Errorf("failed to create directory for '%v': %w", path, err)
	}
	if err := ioutil.WriteFile(path, []byte(newContent), 0666); err != nil {
		return fmt.Errorf("failed to write file '%v': %w", path, err)
	}
	return nil
}

var copyrightRegex = regexp.MustCompile(`// Copyright (\d+) The`)

const header = `// Copyright %v The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

////////////////////////////////////////////////////////////////////////////////
// File generated by tools/src/cmd/gen
// using the template:
//   %v
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////

`

type generator struct {
	template  *template.Template
	cache     *genCache
	writeFile WriteFile
	rnd       *rand.Rand
}

// WriteFile is a function that Generate() may call to emit a new file from a
// template.
// relPath is the relative path from the currently executing template.
// content is the file content to write.
type WriteFile func(relPath, content string) error

// generate executes the template tmpl, writing the output to w.
// See https://golang.org/pkg/text/template/ for documentation on the template
// syntax.
func generate(tmpl string, cache *genCache, w io.Writer, writeFile WriteFile) error {
	g := generator{
		template:  template.New("<template>"),
		cache:     cache,
		writeFile: writeFile,
		rnd:       rand.New(rand.NewSource(4561123)),
	}
	if err := g.bindAndParse(g.template, tmpl); err != nil {
		return err
	}
	return g.template.Execute(w, nil)
}

func (g *generator) bindAndParse(t *template.Template, text string) error {
	_, err := t.Funcs(map[string]interface{}{
		"Map":                   newMap,
		"Iterate":               iterate,
		"Title":                 strings.Title,
		"PascalCase":            pascalCase,
		"SplitDisplayName":      gen.SplitDisplayName,
		"Contains":              strings.Contains,
		"HasPrefix":             strings.HasPrefix,
		"HasSuffix":             strings.HasSuffix,
		"TrimPrefix":            strings.TrimPrefix,
		"TrimSuffix":            strings.TrimSuffix,
		"TrimLeft":              strings.TrimLeft,
		"TrimRight":             strings.TrimRight,
		"Split":                 strings.Split,
		"Scramble":              g.scramble,
		"IsEnumEntry":           is(sem.EnumEntry{}),
		"IsEnumMatcher":         is(sem.EnumMatcher{}),
		"IsFQN":                 is(sem.FullyQualifiedName{}),
		"IsInt":                 is(1),
		"IsTemplateEnumParam":   is(sem.TemplateEnumParam{}),
		"IsTemplateNumberParam": is(sem.TemplateNumberParam{}),
		"IsTemplateTypeParam":   is(sem.TemplateTypeParam{}),
		"IsType":                is(sem.Type{}),
		"ElementType":           gen.ElementType,
		"DeepestElementType":    gen.DeepestElementType,
		"IsAbstract":            gen.IsAbstract,
		"IsDeclarable":          gen.IsDeclarable,
		"OverloadUsesF16":       gen.OverloadUsesF16,
		"IsFirstIn":             isFirstIn,
		"IsLastIn":              isLastIn,
		"Sem":                   g.cache.sem,
		"IntrinsicTable":        g.cache.intrinsicTable,
		"Permute":               g.cache.permute,
		"Eval":                  g.eval,
		"Import":                g.importTmpl,
		"WriteFile":             func(relPath, content string) (string, error) { return "", g.writeFile(relPath, content) },
	}).Option("missingkey=error").Parse(text)
	return err
}

// eval executes the sub-template with the given name and argument, returning
// the generated output
func (g *generator) eval(template string, args ...interface{}) (string, error) {
	target := g.template.Lookup(template)
	if target == nil {
		return "", fmt.Errorf("template '%v' not found", template)
	}
	sb := strings.Builder{}

	var err error
	if len(args) == 1 {
		err = target.Execute(&sb, args[0])
	} else {
		m := newMap()
		if len(args)%2 != 0 {
			return "", fmt.Errorf("Eval expects a single argument or list name-value pairs")
		}
		for i := 0; i < len(args); i += 2 {
			name, ok := args[i].(string)
			if !ok {
				return "", fmt.Errorf("Eval argument %v is not a string", i)
			}
			m.Put(name, args[i+1])
		}
		err = target.Execute(&sb, m)
	}

	if err != nil {
		return "", fmt.Errorf("while evaluating '%v': %v", template, err)
	}
	return sb.String(), nil
}

// importTmpl parses the template at the given project-relative path, merging
// the template definitions into the global namespace.
// Note: The body of the template is not executed.
func (g *generator) importTmpl(path string) (string, error) {
	if strings.Contains(path, "..") {
		return "", fmt.Errorf("import path must not contain '..'")
	}
	path = filepath.Join(fileutils.DawnRoot(), path)
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return "", fmt.Errorf("failed to open '%v': %w", path, err)
	}
	t := g.template.New("")
	if err := g.bindAndParse(t, string(data)); err != nil {
		return "", fmt.Errorf("failed to parse '%v': %w", path, err)
	}
	return "", nil
}

// scramble randomly modifies the input string so that it is no longer equal to
// any of the strings in 'avoid'.
func (g *generator) scramble(str string, avoid container.Set[string]) (string, error) {
	bytes := []byte(str)
	passes := g.rnd.Intn(5) + 1

	const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"

	char := func() byte { return chars[g.rnd.Intn(len(chars))] }
	replace := func(at int) { bytes[at] = char() }
	delete := func(at int) { bytes = append(bytes[:at], bytes[at+1:]...) }
	insert := func(at int) { bytes = append(append(bytes[:at], char()), bytes[at:]...) }

	for i := 0; i < passes || avoid.Contains(string(bytes)); i++ {
		if len(bytes) > 0 {
			at := g.rnd.Intn(len(bytes))
			switch g.rnd.Intn(3) {
			case 0:
				replace(at)
			case 1:
				delete(at)
			case 2:
				insert(at)
			}
		} else {
			insert(0)
		}
	}
	return string(bytes), nil
}

// Map is a simple generic key-value map, which can be used in the template
type Map map[interface{}]interface{}

func newMap() Map { return Map{} }

// Put adds the key-value pair into the map.
// Put always returns an empty string so nothing is printed in the template.
func (m Map) Put(key, value interface{}) string {
	m[key] = value
	return ""
}

// Get looks up and returns the value with the given key. If the map does not
// contain the given key, then nil is returned.
func (m Map) Get(key interface{}) interface{} {
	return m[key]
}

// is returns a function that returns true if the value passed to the function
// matches the type of 'ty'.
func is(ty interface{}) func(interface{}) bool {
	rty := reflect.TypeOf(ty)
	return func(v interface{}) bool {
		ty := reflect.TypeOf(v)
		return ty == rty || ty == reflect.PtrTo(rty)
	}
}

// isFirstIn returns true if v is the first element of the given slice.
func isFirstIn(v, slice interface{}) bool {
	s := reflect.ValueOf(slice)
	count := s.Len()
	if count == 0 {
		return false
	}
	return s.Index(0).Interface() == v
}

// isFirstIn returns true if v is the last element of the given slice.
func isLastIn(v, slice interface{}) bool {
	s := reflect.ValueOf(slice)
	count := s.Len()
	if count == 0 {
		return false
	}
	return s.Index(count-1).Interface() == v
}

// iterate returns a slice of length 'n', with each element equal to its index.
// Useful for: {{- range Iterate $n -}}<this will be looped $n times>{{end}}
func iterate(n int) []int {
	out := make([]int, n)
	for i := range out {
		out[i] = i
	}
	return out
}

// pascalCase returns the snake-case string s transformed into 'PascalCase',
// Rules:
// * The first letter of the string is capitalized
// * Characters following an underscore or number are capitalized
// * Underscores are removed from the returned string
// See: https://en.wikipedia.org/wiki/Camel_case
func pascalCase(s string) string {
	b := strings.Builder{}
	upper := true
	for _, r := range s {
		if r == '_' {
			upper = true
			continue
		}
		if upper {
			b.WriteRune(unicode.ToUpper(r))
			upper = false
		} else {
			b.WriteRune(r)
		}
		if unicode.IsNumber(r) {
			upper = true
		}
	}
	return b.String()
}

// Invokes the clang-format executable at 'exe' to format the file content 'in'.
// Returns the formatted file.
func clangFormat(in, exe string) (string, error) {
	cmd := exec.Command(exe)
	cmd.Stdin = strings.NewReader(in)
	out, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("clang-format failed:\n%v\n%v", string(out), err)
	}
	return string(out), nil
}

// Looks for clang-format in the 'buildtools' directory, falling back to PATH
func findClangFormat(projectRoot string) string {
	var path string
	switch runtime.GOOS {
	case "linux":
		path = filepath.Join(projectRoot, "buildtools/linux64/clang-format")
	case "darwin":
		path = filepath.Join(projectRoot, "buildtools/mac/clang-format")
	case "windows":
		path = filepath.Join(projectRoot, "buildtools/win/clang-format.exe")
	}
	if fileutils.IsExe(path) {
		return path
	}
	var err error
	path, err = exec.LookPath("clang-format")
	if err == nil {
		return path
	}
	return ""
}
