// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package deqp provides functions for running dEQP, as well as loading and storing the results.
package deqp

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"

	"../cause"
	"../cov"
	"../shell"
	"../testlist"
	"../util"
)

const dataVersion = 1

var (
	// Regular expression to parse the output of a dEQP test.
	deqpRE = regexp.MustCompile(`(Fail|Pass|NotSupported|CompatibilityWarning|QualityWarning|InternalError) \(([^\)]*)\)`)
	// Regular expression to parse a test that failed due to UNIMPLEMENTED()
	unimplementedRE = regexp.MustCompile(`[^\n]*UNIMPLEMENTED:[^\n]*`)
	// Regular expression to parse a test that failed due to UNSUPPORTED()
	unsupportedRE = regexp.MustCompile(`[^\n]*UNSUPPORTED:[^\n]*`)
	// Regular expression to parse a test that failed due to UNREACHABLE()
	unreachableRE = regexp.MustCompile(`[^\n]*UNREACHABLE:[^\n]*`)
	// Regular expression to parse a test that failed due to ASSERT()
	assertRE = regexp.MustCompile(`[^\n]*ASSERT\([^\)]*\)[^\n]*`)
	// Regular expression to parse a test that failed due to ABORT()
	abortRE = regexp.MustCompile(`[^\n]*ABORT:[^\n]*`)
)

// Config contains the inputs required for running dEQP on a group of test lists.
type Config struct {
	ExeEgl           string
	ExeGles2         string
	ExeGles3         string
	ExeVulkan        string
	TempDir          string // Directory for temporary log files, coverage output.
	TestLists        testlist.Lists
	Env              []string
	LogReplacements  map[string]string
	NumParallelTests int
	CoverageEnv      *cov.Env
	TestTimeout      time.Duration
	ValidationLayer  bool
}

// Results holds the results of tests across all APIs.
// The Results structure may be serialized to cache results.
type Results struct {
	Version  int
	Error    string
	Tests    map[string]TestResult
	Coverage *cov.Tree
	Duration time.Duration
}

// TestResult holds the results of a single dEQP test.
type TestResult struct {
	Test      string
	Status    testlist.Status
	TimeTaken time.Duration
	Err       string `json:",omitempty"`
	Coverage  *cov.Coverage
}

func (r TestResult) String() string {
	if r.Err != "" {
		return fmt.Sprintf("%s: %s (%s)", r.Test, r.Status, r.Err)
	}
	return fmt.Sprintf("%s: %s", r.Test, r.Status)
}

// LoadResults loads cached test results from disk.
func LoadResults(path string) (*Results, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't open '%s' for loading test results", path)
	}
	defer f.Close()

	var out Results
	if err := json.NewDecoder(f).Decode(&out); err != nil {
		return nil, err
	}
	if out.Version != dataVersion {
		return nil, errors.New("Data is from an old version")
	}
	return &out, nil
}

// Save saves (caches) test results to disk.
func (r *Results) Save(path string) error {
	if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
		return cause.Wrap(err, "couldn't make '%s' for saving test results", filepath.Dir(path))
	}

	f, err := os.Create(path)
	if err != nil {
		return cause.Wrap(err, "Couldn't open '%s' for saving test results", path)
	}
	defer f.Close()

	enc := json.NewEncoder(f)
	enc.SetIndent("", "  ")
	if err := enc.Encode(r); err != nil {
		return cause.Wrap(err, "Couldn't encode test results")
	}

	return nil
}

// Run runs all the tests.
func (c *Config) Run() (*Results, error) {
	start := time.Now()

	if c.TempDir == "" {
		dir, err := ioutil.TempDir("", "deqp")
		if err != nil {
			return nil, cause.Wrap(err, "Could not generate temporary directory")
		}
		c.TempDir = dir
	}

	// Wait group that completes once all the tests have finished.
	wg := sync.WaitGroup{}
	results := make(chan TestResult, 256)

	numTests := 0

	goroutineIndex := 0

	// For each API that we are testing
	for _, list := range c.TestLists {
		// Resolve the test runner
		exe, supportsCoverage := "", false

		switch list.API {
		case testlist.EGL:
			exe = c.ExeEgl
		case testlist.GLES2:
			exe = c.ExeGles2
		case testlist.GLES3:
			exe = c.ExeGles3
		case testlist.Vulkan:
			exe, supportsCoverage = c.ExeVulkan, true
		default:
			return nil, fmt.Errorf("Unknown API '%v'", list.API)
		}
		if !util.IsFile(exe) {
			return nil, fmt.Errorf("Couldn't find dEQP executable at '%s'", exe)
		}

		// Build a chan for the test names to be run.
		tests := make(chan string, len(list.Tests))

		numParallelTests := c.NumParallelTests
		if list.API != testlist.Vulkan {
			// OpenGL tests attempt to open lots of X11 display connections,
			// which may cause us to run out of handles. This maximum was
			// determined experimentally on a 72-core system.
			maxParallelGLTests := 16

			if numParallelTests > maxParallelGLTests {
				numParallelTests = maxParallelGLTests
			}
		}

		// Start a number of go routines to run the tests.
		wg.Add(numParallelTests)
		for i := 0; i < numParallelTests; i++ {
			go func(index int) {
				c.TestRoutine(exe, tests, results, index, supportsCoverage)
				wg.Done()
			}(goroutineIndex)
			goroutineIndex++
		}

		// Shuffle the test list.
		// This attempts to mix heavy-load tests with lighter ones.
		shuffled := make([]string, len(list.Tests))
		for i, j := range rand.New(rand.NewSource(42)).Perm(len(list.Tests)) {
			shuffled[i] = list.Tests[j]
		}

		// Hand the tests to the TestRoutines.
		for _, t := range shuffled {
			tests <- t
		}

		// Close the tests chan to indicate that there are no more tests to run.
		// The TestRoutine functions will return once all tests have been
		// run.
		close(tests)

		numTests += len(list.Tests)
	}

	out := Results{
		Version: dataVersion,
		Tests:   map[string]TestResult{},
	}

	if c.CoverageEnv != nil {
		out.Coverage = &cov.Tree{}
		out.Coverage.Add(cov.Path{}, c.CoverageEnv.AllSourceFiles())
	}

	// Collect the results.
	finished := make(chan struct{})
	lastUpdate := time.Now()
	go func() {
		start, i := time.Now(), 0
		for r := range results {
			i++
			if time.Since(lastUpdate) > time.Minute {
				lastUpdate = time.Now()
				remaining := numTests - i
				log.Printf("Ran %d/%d tests (%v%%). Estimated completion in %v.\n",
					i, numTests, util.Percent(i, numTests),
					(time.Since(start)/time.Duration(i))*time.Duration(remaining))
			}
			out.Tests[r.Test] = r
			if r.Coverage != nil {
				path := strings.Split(r.Test, ".")
				out.Coverage.Add(cov.Path(path), r.Coverage)
				r.Coverage = nil // Free memory
			}
		}
		close(finished)
	}()

	wg.Wait()      // Block until all the deqpTestRoutines have finished.
	close(results) // Signal no more results.
	<-finished     // And wait for the result collecting go-routine to finish.

	out.Duration = time.Since(start)

	return &out, nil
}

// TestRoutine repeatedly runs the dEQP test executable exe with the tests
// taken from tests. The output of the dEQP test is parsed, and the test result
// is written to results.
// TestRoutine only returns once the tests chan has been closed.
// TestRoutine does not close the results chan.
func (c *Config) TestRoutine(exe string, tests <-chan string, results chan<- TestResult, goroutineIndex int, supportsCoverage bool) {
	// Context for the GCOV_PREFIX environment variable:
	// If you compile SwiftShader with gcc and the --coverage flag, the build will contain coverage instrumentation.
	// We can use this to get the code coverage of SwiftShader from running dEQP.
	// The coverage instrumentation reads the existing coverage files on start-up (at a hardcoded path alongside the
	// SwiftShader build), updates coverage info as the programs runs, then (over)writes the coverage files on exit.
	// Thus, multiple parallel processes will race when updating coverage information. The GCOV_PREFIX environment
	// variable adds a prefix to the hardcoded paths.
	// E.g. Given GCOV_PREFIX=/tmp/coverage, the hardcoded path /ss/build/a.gcno becomes /tmp/coverage/ss/build/a.gcno.
	// This is mainly intended for running the target program on a different machine where the hardcoded paths don't
	// make sense. It can also be used to avoid races. It would be trivial to avoid races if the GCOV_PREFIX variable
	// supported macro variables like the Clang code coverage "%p" variable that expands to the process ID; in this
	// case, we could use GCOV_PREFIX=/tmp/coverage/%p to avoid races. Unfortunately, gcc does not support this.
	// Furthermore, processing coverage information from many directories can be slow; we start a lot of dEQP child
	// processes, each of which will likely get a unique process ID. In practice, we only need one directory per go
	// routine.

	// If GCOV_PREFIX is in Env, replace occurrences of "PROC_ID" in GCOV_PREFIX with goroutineIndex.
	// This avoids races between parallel child processes reading and writing coverage output files.
	// For example, GCOV_PREFIX="/tmp/gcov_output/PROC_ID" becomes GCOV_PREFIX="/tmp/gcov_output/1" in the first go routine.
	// You might expect PROC_ID to be the process ID of some process, but the only real requirement is that
	// it is a unique ID between the *parallel* child processes.
	env := make([]string, 0, len(c.Env))
	for _, v := range c.Env {
		if strings.HasPrefix(v, "GCOV_PREFIX=") {
			v = strings.ReplaceAll(v, "PROC_ID", strconv.Itoa(goroutineIndex))
		}
		env = append(env, v)
	}

	coverageFile := filepath.Join(c.TempDir, fmt.Sprintf("%v.profraw", goroutineIndex))
	if supportsCoverage {
		if c.CoverageEnv != nil {
			env = cov.AppendRuntimeEnv(env, coverageFile)
		}
	}

	logPath := "/dev/null" // TODO(bclayton): Try "nul" on windows.
	if !util.IsFile(logPath) {
		logPath = filepath.Join(c.TempDir, fmt.Sprintf("%v.log", goroutineIndex))
	}

nextTest:
	for name := range tests {
		// log.Printf("Running test '%s'\n", name)

		start := time.Now()
		// Set validation layer according to flag.
		validation := "disable"
		if c.ValidationLayer {
			validation = "enable"
		}

		outRaw, err := shell.Exec(c.TestTimeout, exe, filepath.Dir(exe), env,
			"--deqp-validation="+validation,
			"--deqp-surface-type=pbuffer",
			"--deqp-shadercache=disable",
			"--deqp-log-images=disable",
			"--deqp-log-shader-sources=disable",
			"--deqp-log-decompiled-spirv=disable",
			"--deqp-log-empty-loginfo=disable",
			"--deqp-log-flush=disable",
			"--deqp-log-filename="+logPath,
			"-n="+name)
		duration := time.Since(start)
		out := string(outRaw)
		out = strings.ReplaceAll(out, exe, "<dEQP>")
		for k, v := range c.LogReplacements {
			out = strings.ReplaceAll(out, k, v)
		}

		var coverage *cov.Coverage
		if c.CoverageEnv != nil && supportsCoverage {
			coverage, err = c.CoverageEnv.Import(coverageFile)
			if err != nil {
				log.Printf("Warning: Failed to process test coverage for test '%v'. %v", name, err)
			}
			os.Remove(coverageFile)
		}

		for _, test := range []struct {
			re *regexp.Regexp
			s  testlist.Status
		}{
			{unimplementedRE, testlist.Unimplemented},
			{unsupportedRE, testlist.Unsupported},
			{unreachableRE, testlist.Unreachable},
			{assertRE, testlist.Assert},
			{abortRE, testlist.Abort},
		} {
			if s := test.re.FindString(out); s != "" {
				results <- TestResult{
					Test:      name,
					Status:    test.s,
					TimeTaken: duration,
					Err:       s,
					Coverage:  coverage,
				}
				continue nextTest
			}
		}

		// Don't treat non-zero error codes as crashes.
		var exitErr *exec.ExitError
		if errors.As(err, &exitErr) {
			if exitErr.ExitCode() != 255 {
				out += fmt.Sprintf("\nProcess terminated with code %d", exitErr.ExitCode())
				err = nil
			}
		}

		switch err.(type) {
		default:
			results <- TestResult{
				Test:      name,
				Status:    testlist.Crash,
				TimeTaken: duration,
				Err:       out,
				Coverage:  coverage,
			}
		case shell.ErrTimeout:
			log.Printf("Timeout for test '%v'\n", name)
			results <- TestResult{
				Test:      name,
				Status:    testlist.Timeout,
				TimeTaken: duration,
				Coverage:  coverage,
			}
		case nil:
			toks := deqpRE.FindStringSubmatch(out)
			if len(toks) < 3 {
				err := fmt.Sprintf("Couldn't parse test '%v' output:\n%s", name, out)
				log.Println("Warning: ", err)
				results <- TestResult{Test: name, Status: testlist.Fail, Err: err, Coverage: coverage}
				continue
			}
			switch toks[1] {
			case "Pass":
				results <- TestResult{Test: name, Status: testlist.Pass, TimeTaken: duration, Coverage: coverage}
			case "NotSupported":
				results <- TestResult{Test: name, Status: testlist.NotSupported, TimeTaken: duration, Coverage: coverage}
			case "CompatibilityWarning":
				results <- TestResult{Test: name, Status: testlist.CompatibilityWarning, TimeTaken: duration, Coverage: coverage}
			case "QualityWarning":
				results <- TestResult{Test: name, Status: testlist.QualityWarning, TimeTaken: duration, Coverage: coverage}
			case "Fail":
				var err string
				if toks[2] != "Fail" {
					err = toks[2]
				}
				results <- TestResult{Test: name, Status: testlist.Fail, Err: err, TimeTaken: duration, Coverage: coverage}
			case "InternalError":
				var err string
				if toks[2] != "InternalError" {
					err = toks[2]
				}
				results <- TestResult{Test: name, Status: testlist.InternalError, Err: err, TimeTaken: duration, Coverage: coverage}
			default:
				err := fmt.Sprintf("Couldn't parse test output:\n%s", out)
				log.Println("Warning: ", err)
				results <- TestResult{Test: name, Status: testlist.Fail, Err: err, TimeTaken: duration, Coverage: coverage}
			}
		}
	}
}
