// 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 (
	"errors"
	"fmt"
	"io"
	"path/filepath"
	"regexp"
	"strings"
	"testing"
)

func TestCallBisectDriver(t *testing.T) {
	withBisectTestContext(t, func(ctx *testContext) {
		ctx.env = []string{
			"BISECT_STAGE=someBisectStage",
			"BISECT_DIR=someBisectDir",
		}
		cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
		if err := verifyPath(cmd, "/usr/bin/python2"); err != nil {
			t.Error(err)
		}
		if err := verifyArgOrder(cmd, "-c", regexp.QuoteMeta(bisectPythonCommand),
			"someBisectStage", "someBisectDir", filepath.Join(ctx.tempDir, gccX86_64+".real"), "--sysroot=.*", mainCc); err != nil {
			t.Error(err)
		}
	})
}

func TestCallBisectDriverWithCCache(t *testing.T) {
	withBisectTestContext(t, func(ctx *testContext) {
		ctx.cfg.useCCache = true
		cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
		if err := verifyPath(cmd, "/usr/bin/python2"); err != nil {
			t.Error(err)
		}
		if err := verifyArgCount(cmd, 1, "/usr/bin/ccache"); err != nil {
			t.Error(err)
		}
		if err := verifyEnvUpdate(cmd, "CCACHE_DIR=.*"); err != nil {
			t.Error(err)
		}
	})
}

func TestDefaultBisectDir(t *testing.T) {
	withBisectTestContext(t, func(ctx *testContext) {
		ctx.env = []string{
			"BISECT_STAGE=someBisectStage",
		}
		cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
		if err := verifyArgOrder(cmd, "-c", regexp.QuoteMeta(bisectPythonCommand),
			"someBisectStage", "/tmp/sysroot_bisect"); err != nil {
			t.Error(err)
		}
	})
}

func TestForwardStdOutAndStdErrAndExitCodeFromBisect(t *testing.T) {
	withBisectTestContext(t, func(ctx *testContext) {
		ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
			fmt.Fprint(stdout, "somemessage")
			fmt.Fprint(stderr, "someerror")
			return newExitCodeError(23)
		}
		exitCode := callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc))
		if exitCode != 23 {
			t.Errorf("unexpected exit code. Got: %d", exitCode)
		}
		if ctx.stdoutString() != "somemessage" {
			t.Errorf("stdout was not forwarded. Got: %s", ctx.stdoutString())
		}
		if ctx.stderrString() != "someerror" {
			t.Errorf("stderr was not forwarded. Got: %s", ctx.stderrString())
		}
	})
}

func TestForwardGeneralErrorFromBisect(t *testing.T) {
	withBisectTestContext(t, func(ctx *testContext) {
		ctx.cmdMock = func(cmd *command, stdout io.Writer, stderr io.Writer) error {
			return errors.New("someerror")
		}
		stderr := ctx.mustFail(callCompiler(ctx, ctx.cfg,
			ctx.newCommand(gccX86_64, mainCc)))
		if err := verifyInternalError(stderr); err != nil {
			t.Fatal(err)
		}
		if !strings.Contains(stderr, "someerror") {
			t.Errorf("unexpected error. Got: %s", stderr)
		}
	})
}

func withBisectTestContext(t *testing.T, work func(ctx *testContext)) {
	withTestContext(t, func(ctx *testContext) {
		// Disable comparing to the old wrapper as that calls the bisect_driver
		// directly from python, and the new wrapper calls it via a separate
		// sub command.
		ctx.cfg.oldWrapperPath = ""
		ctx.env = []string{"BISECT_STAGE=xyz"}
		work(ctx)
	})
}
