// Copyright 2019 The Chromium OS 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 goldenRecordSection struct {
	Name             string `json:"name"`
	ignoreOldWrapper bool
	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, goldenFile string, sections []goldenRecordSection) {
	if filterPattern := *filterGoldenTests; filterPattern != "" {
		sections = filterGoldenRecords(filterPattern, sections)
	}
	if len(sections) == 0 {
		ctx.t.Errorf("No goldenrecords given.")
		return
	}
	sections = fillGoldenResults(ctx, sections)
	if *updateGoldenFiles {
		log.Printf("updating golden file under %s", goldenFile)
		if err := os.MkdirAll(filepath.Dir(goldenFile), 0777); err != nil {
			ctx.t.Fatal(err)
		}
		goldenFile, err := os.Create(goldenFile)
		if err != nil {
			ctx.t.Fatal(err)
		}
		defer goldenFile.Close()

		writeGoldenRecords(ctx, goldenFile, sections)
	} else {
		compareBuffer := &bytes.Buffer{}
		writeGoldenRecords(ctx, compareBuffer, sections)
		goldenFileData, err := ioutil.ReadFile(goldenFile)
		if err != nil {
			ctx.t.Fatal(err)
		}
		if !bytes.Equal(compareBuffer.Bytes(), goldenFileData) {
			ctx.t.Fatalf("Commands don't match the golden file under %s. Please regenerate via -updategolden to check the differences.",
				goldenFile)
		}
	}
}

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

func fillGoldenResults(ctx *testContext, sections []goldenRecordSection) []goldenRecordSection {
	oldWrapperPath := ctx.cfg.oldWrapperPath
	newSections := []goldenRecordSection{}
	for _, section := range sections {
		ctx.cfg.oldWrapperPath = oldWrapperPath
		if section.ignoreOldWrapper {
			ctx.cfg.oldWrapperPath = ""
		}

		newRecords := []goldenRecord{}
		for _, record := range section.Records {
			newCmds := []commandResult{}
			ctx.cmdMock = func(cmd *command, 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
				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)
		}
		section.Records = newRecords
		newSections = append(newSections, section)
	}
	return newSections
}

func writeGoldenRecords(ctx *testContext, writer io.Writer, sections []goldenRecordSection) {
	// 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(ctx.tempDir),
		new:    []byte(stableTempDir),
	}
	enc := json.NewEncoder(writer)
	enc.SetIndent("", "  ")
	if err := enc.Encode(sections); 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) {
	p = bytes.ReplaceAll(p, writer.old, writer.new)
	return writer.Writer.Write(p)
}
