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

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

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/cmd/builtin-gen/gen"
	"dawn.googlesource.com/dawn/tools/src/cmd/builtin-gen/parser"
	"dawn.googlesource.com/dawn/tools/src/cmd/builtin-gen/resolver"
	"dawn.googlesource.com/dawn/tools/src/fileutils"
	"dawn.googlesource.com/dawn/tools/src/glob"
)

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

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

func showUsage() {
	fmt.Println(`
builtin-gen generates the builtin table for the Tint compiler

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

usage:
  builtin-gen

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

func run() error {
	// Load the builtins definition file
	projectRoot := fileutils.ProjectRoot()
	defPath := filepath.Join(projectRoot, defProjectRelPath)

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

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

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

	// Recursively find all the template files in the <tint>/src directory
	files, err := glob.Scan(projectRoot, glob.MustParseConfig(`{
		"paths": [{"include": [
			"src/tint/**.tmpl",
			"test/tint/**.tmpl"
		]}]
	}`))
	if err != nil {
		return err
	}

	// For each template file...
	for _, relTmplPath := range files {
		// Make tmplPath absolute
		tmplPath := filepath.Join(projectRoot, relTmplPath)

		// 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
		// relpath is a path relative to the template
		writeFile := func(relpath, body string) error {
			// Write the common file header
			sb := strings.Builder{}
			sb.WriteString(fmt.Sprintf(header, filepath.ToSlash(relTmplPath), filepath.ToSlash(defProjectRelPath)))
			sb.WriteString(body)
			content := sb.String()
			abspath := filepath.Join(filepath.Dir(tmplPath), relpath)
			return writeFileIfChanged(abspath, content)
		}

		// Write the content generated using the template and semantic info
		sb := strings.Builder{}
		if err := gen.Generate(sem, string(tmpl), &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")
			if err := writeFile(outFileName, body); err != nil {
				return err
			}
		}
	}

	return nil
}

// writes content to path if the file has changed
func writeFileIfChanged(path, content string) error {
	existing, err := ioutil.ReadFile(path)
	if err == nil && string(existing) == content {
		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(content), 0666); err != nil {
		return fmt.Errorf("failed to write file '%v': %w", path, err)
	}
	return nil
}

const header = `// 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.

////////////////////////////////////////////////////////////////////////////////
// File generated by tools/builtin-gen
// using the template:
//   %v
// and the builtin defintion file:
//   %v
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////

`
