// 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 node

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"time"

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

// runTestCasesWithCmdline() calls the CTS command-line test runner to run each
// test case in a separate process. This reduces possibility of state leakage
// between tests.
// Up to c.flags.numRunners tests will be run concurrently.
func (c *cmd) runTestCasesWithCmdline(ctx context.Context, testCases []common.TestCase, results chan<- common.Result) {
	// Create a chan of test indices.
	// This will be read by the test runner goroutines.
	testCaseIndices := make(chan int, 256)
	go func() {
		for i := range testCases {
			testCaseIndices <- i
		}
		close(testCaseIndices)
	}()

	// Spin up the test runner goroutines
	wg := &sync.WaitGroup{}
	for i := 0; i < c.flags.NumRunners; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for idx := range testCaseIndices {
				res := c.runTestCaseWithCmdline(ctx, testCases[idx])
				res.Index = idx
				results <- res
				if err := ctx.Err(); err != nil {
					return
				}
			}
		}()
	}
	wg.Wait()
}

// runTestCaseWithCmdline() runs a single CTS test case with the command line tool,
// returning the test result.
func (c *cmd) runTestCaseWithCmdline(ctx context.Context, testCase common.TestCase) common.Result {
	ctx, cancel := context.WithTimeout(ctx, common.TestCaseTimeout)
	defer cancel()

	args := []string{
		"-e", "require('./out-node/common/runtime/cmdline.js');",
		"--",
		// src/common/runtime/helper/sys.ts expects 'node file.js <args>'
		// and slices away the first two arguments. When running with '-e', args
		// start at 1, so just inject a placeholder argument.
		"placeholder-arg",
		// Actual arguments begin here
		"--gpu-provider", filepath.Join(c.flags.bin, "cts.js"),
		"--verbose", // always required to emit test pass results
		"--quiet",
	}
	if c.flags.Verbose {
		args = append(args, "--gpu-provider-flag", "verbose=1")
	}
	if c.coverage != nil {
		args = append(args, "--coverage")
	}
	if c.flags.Colors {
		args = append(args, "--colors")
	}
	if c.flags.unrollConstEvalLoops {
		args = append(args, "--unroll-const-eval-loops")
	}
	if c.flags.compatibilityMode {
		args = append(args, "--compat")
	}
	if c.flags.enforceDefaultLimits {
		args = append(args, "--enforce-default-limits")
	}
	for _, f := range c.flags.dawn {
		args = append(args, "--gpu-provider-flag", f)
	}
	args = append(args, string(testCase))

	cmd := exec.CommandContext(ctx, c.flags.Node, args...)
	cmd.Dir = c.flags.CTS

	var buf bytes.Buffer
	cmd.Stdout = &buf
	cmd.Stderr = &buf

	if c.flags.Verbose {
		PrintCommand(cmd, c.flags.skipVSCodeInfo)
	}

	start := time.Now()
	err := cmd.Run()

	msg := buf.String()
	res := common.Result{
		TestCase: testCase,
		Status:   common.Pass,
		Message:  msg,
		Error:    err,
		Duration: time.Since(start),
	}

	if err == nil && c.coverage != nil {
		const header = "Code-coverage: [["
		const footer = "]]"
		if headerStart := strings.Index(msg, header); headerStart >= 0 {
			if footerStart := strings.Index(msg[headerStart:], footer); footerStart >= 0 {
				footerStart += headerStart
				path := msg[headerStart+len(header) : footerStart]
				res.Message = msg[:headerStart] + msg[footerStart+len(footer):] // Strip out the coverage from the message
				coverage, covErr := c.coverage.Env.Import(path)
				os.Remove(path)
				if covErr == nil {
					res.Coverage = coverage
				} else {
					err = fmt.Errorf("could not import coverage data from '%v': %v", path, covErr)
				}
			}
		}
		if err == nil && res.Coverage == nil {
			err = fmt.Errorf("failed to parse code coverage from output")
		}
	}

	switch {
	case errors.Is(err, context.DeadlineExceeded):
		res.Status = common.Timeout
	case err != nil, strings.Contains(msg, "[fail]"):
		res.Status = common.Fail
	case strings.Contains(msg, "[warn]"):
		res.Status = common.Warn
	case strings.Contains(msg, "[skip]"):
		res.Status = common.Skip
	case strings.Contains(msg, "[pass]"):
		break
	default:
		res.Status = common.Fail
		msg += "\ncould not parse test output"
	}

	if res.Error != nil {
		res.Message = fmt.Sprint(res.Message, res.Error)
	}
	return res
}
