// Copyright 2019 The ChromiumOS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var updateGoldenFiles = flag.Bool("updategolden", false, "update golden files")
var filterGoldenTests = flag.String("rungolden", "", "regex filter for golden tests to run")

type goldenFile struct {
	Name    string         `json:"name"`
	Records []goldenRecord `json:"records"`
}

type goldenRecord struct {
	Wd  string   `json:"wd"`
	Env []string `json:"env,omitempty"`
	// runGoldenRecords will read cmd and fill
	// stdout, stderr, exitCode.
	WrapperCmd commandResult `json:"wrapper"`
	// runGoldenRecords will read stdout, stderr, err
	// and fill cmd
	Cmds []commandResult `json:"cmds"`
}

func newGoldenCmd(path string, args ...string) commandResult {
	return commandResult{
		Cmd: &command{
			Path: path,
			Args: args,
		},
	}
}

var okResult = commandResult{}
var okResults = []commandResult{okResult}
var errorResult = commandResult{
	ExitCode: 1,
	Stderr:   "someerror",
	Stdout:   "somemessage",
}
var errorResults = []commandResult{errorResult}

func runGoldenRecords(ctx *testContext, goldenDir string, files []goldenFile) {
	if filterPattern := *filterGoldenTests; filterPattern != "" {
		files = filterGoldenRecords(filterPattern, files)
	}
	if len(files) == 0 {
		ctx.t.Errorf("No goldenrecords given.")
		return
	}
	files = fillGoldenResults(ctx, files)
	if *updateGoldenFiles {
		log.Printf("updating golden files under %s", goldenDir)
		if err := os.MkdirAll(goldenDir, 0777); err != nil {
			ctx.t.Fatal(err)
		}
		for _, file := range files {
			fileHandle, err := os.Create(filepath.Join(goldenDir, file.Name))
			if err != nil {
				ctx.t.Fatal(err)
			}
			defer fileHandle.Close()

			writeGoldenRecords(ctx, fileHandle, file.Records)
		}
	} else {
		for _, file := range files {
			compareBuffer := &bytes.Buffer{}
			writeGoldenRecords(ctx, compareBuffer, file.Records)
			filePath := filepath.Join(goldenDir, file.Name)
			goldenFileData, err := ioutil.ReadFile(filePath)
			if err != nil {
				ctx.t.Error(err)
				continue
			}
			if !bytes.Equal(compareBuffer.Bytes(), goldenFileData) {
				ctx.t.Errorf("Commands don't match the golden file under %s. Please regenerate via -updategolden to check the differences.",
					filePath)
			}
		}
	}
}

func filterGoldenRecords(pattern string, files []goldenFile) []goldenFile {
	matcher := regexp.MustCompile(pattern)
	newFiles := []goldenFile{}
	for _, file := range files {
		newRecords := []goldenRecord{}
		for _, record := range file.Records {
			cmd := record.WrapperCmd.Cmd
			str := strings.Join(append(append(record.Env, cmd.Path), cmd.Args...), " ")
			if matcher.MatchString(str) {
				newRecords = append(newRecords, record)
			}
		}
		file.Records = newRecords
		newFiles = append(newFiles, file)
	}
	return newFiles
}

func fillGoldenResults(ctx *testContext, files []goldenFile) []goldenFile {
	newFiles := []goldenFile{}
	for _, file := range files {
		newRecords := []goldenRecord{}
		for _, record := range file.Records {
			newCmds := []commandResult{}
			ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
				if len(newCmds) >= len(record.Cmds) {
					ctx.t.Errorf("Not enough commands specified for wrapperCmd %#v and env %#v. Expected: %#v",
						record.WrapperCmd.Cmd, record.Env, record.Cmds)
					return nil
				}
				cmdResult := record.Cmds[len(newCmds)]
				cmdResult.Cmd = cmd
				if numEnvUpdates := len(cmdResult.Cmd.EnvUpdates); numEnvUpdates > 0 {
					if strings.HasPrefix(cmdResult.Cmd.EnvUpdates[numEnvUpdates-1], "PYTHONPATH") {
						cmdResult.Cmd.EnvUpdates[numEnvUpdates-1] = "PYTHONPATH=/somepath/test_binary"
					}
				}
				newCmds = append(newCmds, cmdResult)
				io.WriteString(stdout, cmdResult.Stdout)
				io.WriteString(stderr, cmdResult.Stderr)
				if cmdResult.ExitCode != 0 {
					return newExitCodeError(cmdResult.ExitCode)
				}
				return nil
			}
			ctx.stdoutBuffer.Reset()
			ctx.stderrBuffer.Reset()
			ctx.env = record.Env
			if record.Wd == "" {
				record.Wd = ctx.tempDir
			}
			ctx.wd = record.Wd
			// Create an empty wrapper at the given path.
			// Needed as we are resolving symlinks which stats the wrapper file.
			ctx.writeFile(record.WrapperCmd.Cmd.Path, "")
			record.WrapperCmd.ExitCode = callCompiler(ctx, ctx.cfg, record.WrapperCmd.Cmd)
			if hasInternalError(ctx.stderrString()) {
				ctx.t.Errorf("found an internal error for wrapperCmd %#v and env #%v. Got: %s",
					record.WrapperCmd.Cmd, record.Env, ctx.stderrString())
			}
			if len(newCmds) < len(record.Cmds) {
				ctx.t.Errorf("Too many commands specified for wrapperCmd %#v and env %#v. Expected: %#v",
					record.WrapperCmd.Cmd, record.Env, record.Cmds)
			}
			record.Cmds = newCmds
			record.WrapperCmd.Stdout = ctx.stdoutString()
			record.WrapperCmd.Stderr = ctx.stderrString()
			newRecords = append(newRecords, record)
		}
		file.Records = newRecords
		newFiles = append(newFiles, file)
	}
	return newFiles
}

func writeGoldenRecords(ctx *testContext, writer io.Writer, records []goldenRecord) {
	// Replace the temp dir with a stable path so that the goldens stay stable.
	stableTempDir := filepath.Join(filepath.Dir(ctx.tempDir), "stable")
	writer = &replacingWriter{
		Writer: writer,
		old:    [][]byte{[]byte(ctx.tempDir)},
		new:    [][]byte{[]byte(stableTempDir)},
	}
	enc := json.NewEncoder(writer)
	enc.SetIndent("", "  ")
	if err := enc.Encode(records); err != nil {
		ctx.t.Fatal(err)
	}
}

type replacingWriter struct {
	io.Writer
	old [][]byte
	new [][]byte
}

func (writer *replacingWriter) Write(p []byte) (n int, err error) {
	// TODO: Use bytes.ReplaceAll once cros sdk uses golang >= 1.12
	for i, old := range writer.old {
		p = bytes.Replace(p, old, writer.new[i], -1)
	}
	return writer.Writer.Write(p)
}
