// Copyright 2023 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 common

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"

	"dawn.googlesource.com/dawn/tools/src/fileutils"
	"dawn.googlesource.com/dawn/tools/src/subcmd"
	"dawn.googlesource.com/dawn/tools/src/term"
)

// Flags holds the common flags for all CTS runners
type Flags struct {
	Verbose          bool
	Colors           bool
	NumRunners       int
	Log              string
	ResultsPath      string
	ExpectationsPath string
	CTS              string // Path to the CTS directory
	Node             string // Path to the Node executable
	Npx              string // Path to the npx executable
}

func (f *Flags) Register() {
	flag.BoolVar(&f.Verbose, "verbose", false, "print extra information while testing")
	flag.BoolVar(&f.Colors, "colors", term.CanUseAnsiEscapeSequences(), "enable / disable colors")
	flag.IntVar(&f.NumRunners, "j", runtime.NumCPU()/2, "number of concurrent runners. 0 runs serially")
	flag.StringVar(&f.Log, "log", "", "path to log file of tests run and result")
	flag.StringVar(&f.ResultsPath, "output", "", "path to write test results file")
	flag.StringVar(&f.ExpectationsPath, "expect", "", "path to expectations file")
	flag.StringVar(&f.CTS, "cts", defaultCtsPath(), "root directory of WebGPU CTS")
	flag.StringVar(&f.Node, "node", fileutils.NodePath(), "path to node executable")
	flag.StringVar(&f.Npx, "npx", defaultNpxPath(), "path to npx executable")
}

// Process processes the flags, returning a State.
// Note: Ensure you call Close() on the returned State
func (f *Flags) Process() (*State, error) {
	s := &State{
		resultsPath: f.ResultsPath,
	}

	// Create the stdout writer
	s.Stdout = term.NewAnsiWriter(f.Colors)

	// Check CTS path
	if f.CTS == "" {
		return nil, subcmd.InvalidCLA()
	}
	if !fileutils.IsDir(f.CTS) {
		return nil, fmt.Errorf("'%v' is not a directory", f.CTS)
	}
	absCTS, err := filepath.Abs(f.CTS)
	if err != nil {
		return nil, fmt.Errorf("unable to get absolute path for '%v'", f.CTS)
	}
	f.CTS = absCTS

	// Build the logger, if needed
	if f.Log != "" {
		writer, err := os.Create(f.Log)
		if err != nil {
			return nil, fmt.Errorf("failed to open log '%v': %w", f.Log, err)
		}
		s.Log = NewLogger(writer)
		s.logWriter = writer
	}

	// If an expectations file was specified, load it.
	if f.ExpectationsPath != "" {
		if err := s.Expectations.Load(f.ExpectationsPath); err != nil {
			return nil, err
		}
	}

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

	s.CTS = NewCTS(f.CTS, f.Npx, f.Node)

	return s, nil
}

// State holds the common state for commands
type State struct {
	Stdout       io.WriteCloser
	Log          Logger
	Expectations Results
	CTS          CTS
	resultsPath  string
	logWriter    io.WriteCloser
}

// Close closes s.Stdout and saves the results to the results path (if set)
func (s *State) Close(results Results) error {
	if err := s.Stdout.Close(); err != nil {
		return err
	}

	// If an result file was specified, save results to it.
	if s.resultsPath != "" {
		if err := results.Save(s.resultsPath); err != nil {
			return err
		}
	}

	if s.logWriter != nil {
		if err := s.logWriter.Close(); err != nil {
			return fmt.Errorf("failed to close log file: %w", err)
		}
	}

	return nil
}

// defaultCtsPath looks for the webgpu-cts directory in dawn's third_party
// directory. This is used as the default for the --cts command line flag.
func defaultCtsPath() string {
	if dawnRoot := fileutils.DawnRoot(); dawnRoot != "" {
		cts := filepath.Join(dawnRoot, "third_party/webgpu-cts")
		if info, err := os.Stat(cts); err == nil && info.IsDir() {
			return cts
		}
	}
	return ""
}

// defaultNpxPath looks for the npx executable on PATH
func defaultNpxPath() string {
	if p, err := exec.LookPath("npx"); err == nil {
		return p
	}
	return ""
}
