// 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/exec"
	"path/filepath"
	"runtime"

	"dawn.googlesource.com/dawn/tools/src/fileutils"
	"dawn.googlesource.com/dawn/tools/src/oswrapper"
	"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
	FailuresOnly     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(fsReader oswrapper.FilesystemReader) {
	flag.BoolVar(&f.Verbose, "verbose", false, "print extra information while testing")
	flag.BoolVar(&f.Colors, "colors", term.CanUseAnsiEscapeSequences(), "enable / disable colors")
	flag.BoolVar(&f.FailuresOnly, "failures-only", false, "output only failures to log file")
	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(fsReader), "root directory of WebGPU CTS")
	flag.StringVar(&f.Node, "node", fileutils.NodePath(fsReader), "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(fsReaderWriter oswrapper.FilesystemReaderWriter) (*State, error) {
	s := &State{
		resultsPath:  f.ResultsPath,
		failuresOnly: f.FailuresOnly,
	}

	// 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, fsReaderWriter) {
		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 := fsReaderWriter.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 Expectations
	CTS          CTS
	resultsPath  string
	failuresOnly bool
	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 != "" {
		expectations := Expectations{}
		for testCase, result := range results {
			if !s.failuresOnly || result.Status == Fail {
				expectations[testCase] = result.Status
			}
		}

		if err := expectations.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)
		}
	}

	if err := AddToListingMeta(s.CTS.path, results); err != nil {
		return 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(fsReader oswrapper.FilesystemReader) string {
	if dawnRoot := fileutils.DawnRoot(fsReader); dawnRoot != "" {
		cts := filepath.Join(dawnRoot, "third_party", "webgpu-cts")
		if info, err := fsReader.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 ""
}
