// 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/tint/tools/src/cmd/builtin-gen/gen"
	"dawn.googlesource.com/tint/tools/src/cmd/builtin-gen/parser"
	"dawn.googlesource.com/tint/tools/src/cmd/builtin-gen/resolver"
	"dawn.googlesource.com/tint/tools/src/fileutils"
	"dawn.googlesource.com/tint/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/**.tmpl",
			"test/**.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
////////////////////////////////////////////////////////////////////////////////

`
