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

package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/cmd/run-cts/common"
	"dawn.googlesource.com/dawn/tools/src/dawn/node"
	"dawn.googlesource.com/dawn/tools/src/fileutils"
	"dawn.googlesource.com/dawn/tools/src/oswrapper"
)

// main entry point
func main() {
	wrapper := oswrapper.GetRealOSWrapper()
	nodeFlags := node.Flags{}
	opts := node.Options{
		AllowUnsafeAPIs: true,
	}

	var nodePath string
	var binDir string
	lldb := false

	flag.Usage = func() {
		out := flag.CommandLine.Output()
		fmt.Fprintf(out, "node runs a .js file with 'navigator.gpu' provided by dawn/node.\n\n")
		flag.PrintDefaults()
	}

	flag.StringVar(&nodePath, "node", fileutils.NodePath(wrapper), "path to node executable")
	flag.Var(&nodeFlags, "flag", "flag to pass to dawn-node as flag=value. multiple flags must be passed in individually")
	flag.StringVar(&binDir, "bin", fileutils.BuildPath(wrapper), "path to the directory holding cts.cjs and dawn.node")
	flag.StringVar(&opts.Backend, "backend", "default", "backend to use: default|null|webgpu|d3d11|d3d12|metal|vulkan|opengl|opengles."+
		" set to 'vulkan' if VK_ICD_FILENAMES environment variable is set, 'default' otherwise")
	flag.StringVar(&opts.Adapter, "adapter", "", "name (or substring) of the GPU adapter to use")
	flag.BoolVar(&opts.Validate, "validate", false, "enable backend validation")
	flag.BoolVar(&opts.DumpShaders, "dump-shaders", false, "dump WGSL shaders. Enables --verbose")
	flag.BoolVar(&opts.DumpShadersPretty, "dump-shaders-pretty", false, "dump WGSL shaders, but don't run symbol renaming. May fail tests that shadow predeclared builtins. Enables --verbose")
	flag.BoolVar(&opts.UseFXC, "fxc", false, "Use FXC instead of DXC. Disables 'use_dxc' Dawn flag")
	flag.BoolVar(&lldb, "lldb", false, "launch node via lldb")
	flag.Parse()

	nodeFlags.SetOptions(opts)

	debugger := ""
	if lldb {
		debugger = "lldb"
	}

	if err := run(binDir, nodePath, nodeFlags, flag.Args(), debugger, wrapper); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

// run starts the
func run(binPath, nodePath string, flags node.Flags, args []string, debugger string, fsReader oswrapper.FilesystemReader) error {
	if len(args) == 0 {
		return fmt.Errorf("missing path to .js file")
	}

	scriptPath, err := filepath.Abs(args[0])
	if err != nil {
		return err
	}

	// Find node
	if nodePath == "" {
		return fmt.Errorf("cannot find path to node. Specify with --node")
	}

	for _, file := range []string{"cts.cjs", "dawn.node"} {
		if !fileutils.IsFile(filepath.Join(binPath, file), fsReader) {
			return fmt.Errorf("'%v' does not contain '%v'", binPath, file)
		}
	}

	ctsJS := filepath.Join(binPath, "cts.cjs")

	ctx := context.Background()
	if debugger == "" {
		timeoutCtx, cancel := context.WithTimeout(context.Background(), common.TestCaseTimeout)
		defer cancel()
		ctx = timeoutCtx
	}

	quotedFlags := make([]string, len(flags))
	for i, f := range flags {
		quotedFlags[i] = fmt.Sprintf("'%v'", f)
	}

	args = []string{
		"-e",
		fmt.Sprintf("const { create } = require('%v'); navigator = { gpu: create([%v]) }; require('%v')", ctsJS, strings.Join(quotedFlags, ", "), scriptPath),
	}

	exe := nodePath

	if debugger != "" {
		args = append([]string{"--", exe}, args...)
		exe, err = exec.LookPath(debugger)
		if err != nil {
			return err
		}
	}

	cmd := exec.CommandContext(ctx, exe, args...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}
