// Package testutils contains convenience utilities for testing.
package testutils

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"text/template"
	"time"

	"github.com/google/uuid"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"

	"go.skia.org/infra/bazel/go/bazel"
	"go.skia.org/infra/go/repo_root"
	"go.skia.org/infra/go/sktest"
	"go.skia.org/infra/go/util"
)

var (
	// TryAgainErr use used by TryUntil.
	TryAgainErr = errors.New("Trying Again")
)

// TestDataDir returns the path to the caller's testdata directory, which
// is assumed to be "<path to caller dir>/testdata".
func TestDataDir(t sktest.TestingT) string {
	_, thisFile, _, ok := runtime.Caller(0)
	require.True(t, ok, "Could not find test data dir: runtime.Caller() failed.")
	for skip := 0; ; skip++ {
		_, file, _, ok := runtime.Caller(skip)
		require.True(t, ok, "Could not find test data dir: runtime.Caller() failed.")
		if file != thisFile {
			// Under Bazel, the path returned by runtime.Caller() is relative to the workspace's root
			// directory (e.g. "go/testutils"). We prepend this with the absolute path to the runfiles
			// directory so that tests can find these files with no further changes.
			//
			// Under "go test" this is not necessary because the path returned by runtime.Caller() is
			// absolute.
			if bazel.InBazelTest() {
				file = filepath.Join(bazel.RunfilesDir(), file)
			}

			return filepath.Join(filepath.Dir(file), "testdata")
		}
	}
}

// ReadFileBytes reads a file from the caller's testdata directory and returns its contents as a
// slice of bytes.
func ReadFileBytes(t sktest.TestingT, filename string) []byte {
	f := GetReader(t, filename)
	b, err := ioutil.ReadAll(f)
	require.NoError(t, err, "Could not read %s: %v", filename)
	require.NoError(t, f.Close())
	return b
}

// ReadFile reads a file from the caller's testdata directory.
func ReadFile(t sktest.TestingT, filename string) string {
	b := ReadFileBytes(t, filename)
	return string(b)
}

// GetReader reads a file from the caller's testdata directory and panics on
// error.
func GetReader(t sktest.TestingT, filename string) io.ReadCloser {
	dir := TestDataDir(t)
	f, err := os.Open(filepath.Join(dir, filename))
	require.NoError(t, err, "Reading %s from testdir", filename)
	return f
}

// ReadJSONFile reads a JSON file from the caller's testdata directory into the
// given interface.
func ReadJSONFile(t sktest.TestingT, filename string, dest interface{}) {
	f := GetReader(t, filename)
	err := json.NewDecoder(f).Decode(dest)
	require.NoError(t, err, "Decoding JSON in %s", filename)
	require.NoError(t, f.Close())
}

// WriteFile writes the given contents to the given file path, reporting any
// error.
func WriteFile(t sktest.TestingT, filename, contents string) {
	require.NoErrorf(t, ioutil.WriteFile(filename, []byte(contents), os.ModePerm), "Unable to write to file %s", filename)
}

// AssertCloses takes an ioutil.Closer and asserts that it closes. E.g.:
// frobber := NewFrobber()
// defer testutils.AssertCloses(t, frobber)
func AssertCloses(t sktest.TestingT, c io.Closer) {
	require.NoError(t, c.Close())
}

// Remove attempts to remove the given file and asserts that no error is returned.
func Remove(t sktest.TestingT, fp string) {
	require.NoError(t, os.Remove(fp))
}

// RemoveAll attempts to remove the given directory and asserts that no error is returned.
func RemoveAll(t sktest.TestingT, fp string) {
	require.NoError(t, os.RemoveAll(fp))
}

// MarshalJSON encodes the given interface to a JSON string.
func MarshalJSON(t sktest.TestingT, i interface{}) string {
	b, err := json.Marshal(i)
	require.NoError(t, err)
	return string(b)
}

// MarshalIndentJSON encodes the given interface to an indented JSON string.
func MarshalIndentJSON(t sktest.TestingT, i interface{}) string {
	b, err := json.MarshalIndent(i, "", "  ")
	require.NoError(t, err)
	return string(b)
}

// GetRepoRoot returns the path to the root of the checkout.
func GetRepoRoot(t sktest.TestingT) string {
	root, err := repo_root.Get()
	require.NoError(t, err)
	return root
}

// EventuallyConsistent tries a test repeatedly until either the test passes
// or time expires, and is used when tests are written to expect
// non-eventual consistency.
//
// Use this function sparingly.
//
// duration - The amount of time to keep trying.
// f - The func to run the tests, should return TryAgainErr if
//     we should keep trying, otherwise TryUntil will return
//     with the err that f() returns.
func EventuallyConsistent(duration time.Duration, f func() error) error {
	begin := time.Now()
	for time.Now().Sub(begin) < duration {
		if err := f(); err != TryAgainErr {
			return err
		}
	}
	return fmt.Errorf("Failed to pass test in allotted time.")
}

// AnyContext can be used to match any Context objects e.g.
// m.On("Foo", testutils.AnyContext).Return(...)
// This is better than trying to used mock.AnythingOfTypeArgument
// because that only works for concrete types, which could be brittle
// (e.g. a "normal" context is *context.emptyCtx, but one modified by
// trace.StartSpan() could be a *context.valueCtx)
var AnyContext = mock.MatchedBy(func(c context.Context) bool {
	// if the passed in parameter does not implement the context.Context interface, the
	// wrapping MatchedBy will panic - so we can simply return true, since we
	// know it's a context.Context if execution flow makes it here.
	return true
})

// ExecTemplate parses the given string as a text template, executes it using
// the given data, and returns the result as a string.
func ExecTemplate(t sktest.TestingT, tmpl string, data interface{}) string {
	template, err := template.New(uuid.New().String()).Parse(tmpl)
	require.NoError(t, err)
	var buf bytes.Buffer
	require.NoError(t, template.Execute(&buf, data))
	return buf.String()
}

// SetUpFakeHomeDir creates a temporary dir and updates the HOME environment variable with its path.
// After the caller test completes, the HOME environment variable will be restored to its original
// value, and the temporary dir will be deleted.
//
// Under Bazel, this is useful because Bazel does not set the HOME environment variable. Without
// this, some tests that call the "go" binary fail, because some "go" subcommands create a cache
// under $HOME/.cache/go-build.
//
// Outside of Bazel (i.e. "go test"), this is still useful because it leads to more hermetic tests
// which do not depend on the specifics of the $HOME directory in the host system.
//
// See https://docs.bazel.build/versions/master/test-encyclopedia.html#initial-conditions.
func SetUpFakeHomeDir(t sktest.TestingT, tempDirPattern string) {
	fakeHome, err := ioutil.TempDir("", tempDirPattern)
	require.NoError(t, err)
	oldHome := os.Getenv("HOME")
	require.NoError(t, os.Setenv("HOME", fakeHome))

	t.Cleanup(func() {
		require.NoError(t, os.Setenv("HOME", oldHome))
		util.RemoveAll(fakeHome)
	})
}
