// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// check-spec-examples tests that WGSL specification examples compile as
// expected.
//
// The tool parses the WGSL HTML specification from the web or from a local file
// and then runs the WGSL compiler for all examples annotated with the 'wgsl'
// and 'global-scope' or 'function-scope' HTML class types.
//
// To run:
//
//	go get golang.org/x/net/html # Only required once
//	go run tools/check-spec-examples/main.go --compiler=<path-to-tint>
package main

import (
	"errors"
	"flag"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/oswrapper"
	"golang.org/x/net/html"
)

const (
	toolName        = "check-spec-examples"
	defaultSpecPath = "https://gpuweb.github.io/gpuweb/wgsl/"
)

var (
	errInvalidArg = errors.New("Invalid arguments")
)

func main() {
	flag.Usage = func() {
		out := flag.CommandLine.Output()
		fmt.Fprintf(out, "%v tests that WGSL specification examples compile as expected.\n", toolName)
		fmt.Fprintf(out, "\n")
		fmt.Fprintf(out, "Usage:\n")
		fmt.Fprintf(out, "  %s [spec] [flags]\n", toolName)
		fmt.Fprintf(out, "\n")
		fmt.Fprintf(out, "spec is an optional local file path or URL to the WGSL specification.\n")
		fmt.Fprintf(out, "If spec is omitted then the specification is fetched from %v\n", defaultSpecPath)
		fmt.Fprintf(out, "\n")
		fmt.Fprintf(out, "flags may be any combination of:\n")
		flag.PrintDefaults()
	}

	err := run(oswrapper.GetRealOSWrapper())
	if err != nil {
		if errors.Is(err, errInvalidArg) {
			fmt.Fprintf(os.Stderr, "Error: %v\n\n", err)
			flag.Usage()
		} else {
			fmt.Fprintf(os.Stderr, "%v\n", err)
		}
		os.Exit(1)
	}
}

// TODO(crbug.com/416755658): Add unittest coverage once exec is handled via
// dependency injection.
func run(osWrapper oswrapper.OSWrapper) error {
	// Parse flags
	compilerPath := flag.String("compiler", "tint", "path to compiler executable")
	verbose := flag.Bool("verbose", false, "print examples that pass")
	flag.Parse()

	// Try to find the WGSL compiler
	compiler, err := exec.LookPath(*compilerPath)
	if err != nil {
		return fmt.Errorf("Failed to find WGSL compiler: %w", err)
	}
	if compiler, err = filepath.Abs(compiler); err != nil {
		return fmt.Errorf("Failed to find WGSL compiler: %w", err)
	}

	// Check for explicit WGSL spec path
	args := flag.Args()
	specURL, _ := url.Parse(defaultSpecPath)
	switch len(args) {
	case 0:
	case 1:
		var err error
		specURL, err = url.Parse(args[0])
		if err != nil {
			return err
		}
	default:
		if len(args) > 1 {
			return errInvalidArg
		}
	}

	// The specURL might just be a local file path, in which case automatically
	// add the 'file' URL scheme
	if specURL.Scheme == "" {
		specURL.Scheme = "file"
	}

	// Open the spec from HTTP(S) or from a local file
	var specContent io.ReadCloser
	switch specURL.Scheme {
	case "http", "https":
		response, err := http.Get(specURL.String())
		if err != nil {
			return fmt.Errorf("Failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		specContent = response.Body
	case "file":
		specURL.Path, err = filepath.Abs(specURL.Path)
		if err != nil {
			return fmt.Errorf("Failed to load the WGSL spec from '%v': %w", specURL, err)
		}

		file, err := osWrapper.Open(specURL.Path)
		if err != nil {
			return fmt.Errorf("Failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		specContent = file
	default:
		return fmt.Errorf("Unsupported URL scheme: %v", specURL.Scheme)
	}
	defer specContent.Close()

	// Create the HTML parser
	doc, err := html.Parse(specContent)
	if err != nil {
		return err
	}

	// Parse all the WGSL examples
	examples := []example{}
	if err := gatherExamples(doc, &examples); err != nil {
		return err
	}

	if len(examples) == 0 {
		return fmt.Errorf("no examples found")
	}

	// Create a temporary directory to hold the examples as separate files
	tmpDir, err := osWrapper.MkdirTemp("", "wgsl-spec-examples")
	if err != nil {
		return err
	}
	if err := osWrapper.MkdirAll(tmpDir, 0666); err != nil {
		return fmt.Errorf("Failed to create temporary directory: %w", err)
	}
	defer osWrapper.RemoveAll(tmpDir)

	// For each compilable WGSL example...
	for _, e := range examples {
		exampleURL := specURL.String() + "#" + e.name

		if err := tryCompile(compiler, tmpDir, e, osWrapper); err != nil {
			if !e.expectError {
				fmt.Printf("✘ %v ✘\n%v\n", exampleURL, err)
				continue
			}
		} else if e.expectError {
			fmt.Printf("✘ %v ✘\nCompiled even though it was marked with 'expect-error'\n", exampleURL)
		}
		if *verbose {
			fmt.Printf("✔ %v ✔\n", exampleURL)
		}
	}
	return nil
}

// Holds all the information about a single, compilable WGSL example in the spec
type example struct {
	name          string // The name (typically hash generated by bikeshed)
	code          string // The example source
	globalScope   bool   // Annotated with 'global-scope' ?
	functionScope bool   // Annotated with 'function-scope' ?
	expectError   bool   // Annotated with 'expect-error' ?
}

// TODO(crbug.com/416755658): Add unittest coverage once exec is handled via
// dependency injection.
// tryCompile attempts to compile the example e in the directory wd, using the
// compiler at the given path. If the example is annotated with 'function-scope'
// then the code is wrapped with a basic vertex-stage-entry function.
// If the first compile fails then a placeholder vertex-state-entry
// function is appended to the source, and another attempt to compile
// the shader is made.
func tryCompile(compiler, wd string, e example, osWrapper oswrapper.OSWrapper) error {
	code := e.code
	if e.functionScope {
		code = "\n@vertex fn main() -> @builtin(position) vec4<f32> {\n" + code + " return vec4<f32>();}\n"
	}

	addedStubFunction := false
	for {
		err := compile(compiler, wd, e.name, code, osWrapper)
		if err == nil {
			return nil
		}

		if !addedStubFunction {
			code += "\n@vertex fn main() {}\n"
			addedStubFunction = true
			continue
		}

		return err
	}
}

// TODO(crbug.com/416755658): Add unittest coverage once exec is handled via
// dependency injection.
// compile creates a file in wd and uses the compiler to attempt to compile it.
func compile(compiler, wd, name, code string, osWrapper oswrapper.OSWrapper) error {
	filename := name + ".wgsl"
	path := filepath.Join(wd, filename)
	if err := osWrapper.WriteFile(path, []byte(code), 0666); err != nil {
		return fmt.Errorf("Failed to write example file '%v'", path)
	}
	cmd := exec.Command(compiler, filename)
	cmd.Dir = wd
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("%v\n%v", err, string(out))
	}
	return nil
}

// gatherExamples scans the HTML node and its children for blocks that contain
// WGSL example code, populating the examples slice.
func gatherExamples(node *html.Node, examples *[]example) error {
	if hasClass(node, "example") && hasClass(node, "wgsl") {
		e := example{
			name:          nodeID(node),
			code:          exampleCode(node),
			globalScope:   hasClass(node, "global-scope"),
			functionScope: hasClass(node, "function-scope"),
			expectError:   hasClass(node, "expect-error"),
		}
		// If the example is annotated with a scope, then it can be compiled.
		if e.globalScope || e.functionScope {
			*examples = append(*examples, e)
		}
	}
	for child := node.FirstChild; child != nil; child = child.NextSibling {
		if err := gatherExamples(child, examples); err != nil {
			return err
		}
	}
	return nil
}

// exampleCode returns a string formed from all the TextNodes found in <pre>
// blocks that are children of node.
func exampleCode(node *html.Node) string {
	sb := strings.Builder{}
	for child := node.FirstChild; child != nil; child = child.NextSibling {
		if child.Data == "pre" {
			printNodeText(child, &sb)
		}
	}
	return sb.String()
}

// printNodeText traverses node and its children, writing the Data of all
// TextNodes to sb.
func printNodeText(node *html.Node, sb *strings.Builder) {
	if node.Type == html.TextNode {
		sb.WriteString(node.Data)
	}

	for child := node.FirstChild; child != nil; child = child.NextSibling {
		printNodeText(child, sb)
	}
}

// hasClass returns true iff node has the given "class" attribute.
func hasClass(node *html.Node, class string) bool {
	for _, attr := range node.Attr {
		if attr.Key == "class" {
			classes := strings.Split(attr.Val, " ")
			for _, c := range classes {
				if c == class {
					return true
				}
			}
		}
	}
	return false
}

// nodeID returns the given "id" attribute of node, or an empty string if there
// is no "id" attribute.
func nodeID(node *html.Node) string {
	for _, attr := range node.Attr {
		if attr.Key == "id" {
			return attr.Val
		}
	}
	return ""
}
