// Copyright 2021 Google LLC
//
// 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 rbcrun

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"testing"

	"go.starlark.net/resolve"
	"go.starlark.net/starlark"
	"go.starlark.net/starlarktest"
)

// In order to use "assert.star" from go/starlark.net/starlarktest in the tests,
// provide:
//  * load function that handles "assert.star"
//  * starlarktest.DataFile function that finds its location

func init() {
	starlarktestSetup()
}

func starlarktestSetup() {
	resolve.AllowLambda = true
	starlarktest.DataFile = func(pkgdir, filename string) string {
		// The caller expects this function to return the path to the
		// data file. The implementation assumes that the source file
		// containing the caller and the data file are in the same
		// directory. It's ugly. Not sure what's the better way.
		// TODO(asmundak): handle Bazel case
		_, starlarktestSrcFile, _, _ := runtime.Caller(1)
		if filepath.Base(starlarktestSrcFile) != "starlarktest.go" {
			panic(fmt.Errorf("this function should be called from starlarktest.go, got %s",
				starlarktestSrcFile))
		}
		return filepath.Join(filepath.Dir(starlarktestSrcFile), filename)
	}
}

// Common setup for the tests: create thread, change to the test directory
func testSetup(t *testing.T, env []string) *starlark.Thread {
	setup(env)
	thread := &starlark.Thread{
		Load: func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
			if module == "assert.star" {
				return starlarktest.LoadAssertModule()
			}
			return nil, fmt.Errorf("load not implemented")
		}}
	starlarktest.SetReporter(thread, t)
	if err := os.Chdir(dataDir()); err != nil {
		t.Fatal(err)
	}
	return thread
}

func dataDir() string {
	_, thisSrcFile, _, _ := runtime.Caller(0)
	return filepath.Join(filepath.Dir(thisSrcFile), "testdata")

}

func exerciseStarlarkTestFile(t *testing.T, starFile string) {
	// In order to use "assert.star" from go/starlark.net/starlarktest in the tests, provide:
	//  * load function that handles "assert.star"
	//  * starlarktest.DataFile function that finds its location
	setup(nil)
	thread := &starlark.Thread{
		Load: func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
			if module == "assert.star" {
				return starlarktest.LoadAssertModule()
			}
			return nil, fmt.Errorf("load not implemented")
		}}
	starlarktest.SetReporter(thread, t)
	_, thisSrcFile, _, _ := runtime.Caller(0)
	filename := filepath.Join(filepath.Dir(thisSrcFile), starFile)
	if _, err := starlark.ExecFile(thread, filename, nil, builtins); err != nil {
		if err, ok := err.(*starlark.EvalError); ok {
			t.Fatal(err.Backtrace())
		}
		t.Fatal(err)
	}
}

func TestCliAndEnv(t *testing.T) {
	// TODO(asmundak): convert this to use exerciseStarlarkTestFile
	if err := os.Setenv("TEST_ENVIRONMENT_FOO", "test_environment_foo"); err != nil {
		t.Fatal(err)
	}
	thread := testSetup(t, []string{"CLI_FOO=foo"})
	if _, err := starlark.ExecFile(thread, "cli_and_env.star", nil, builtins); err != nil {
		if err, ok := err.(*starlark.EvalError); ok {
			t.Fatal(err.Backtrace())
		}
		t.Fatal(err)
	}
}

func TestFileOps(t *testing.T) {
	// TODO(asmundak): convert this to use exerciseStarlarkTestFile
	if err := os.Setenv("TEST_DATA_DIR", dataDir()); err != nil {
		t.Fatal(err)
	}
	thread := testSetup(t, nil)
	if _, err := starlark.ExecFile(thread, "file_ops.star", nil, builtins); err != nil {
		if err, ok := err.(*starlark.EvalError); ok {
			t.Fatal(err.Backtrace())
		}
		t.Fatal(err)
	}
}

func TestLoad(t *testing.T) {
	// TODO(asmundak): convert this to use exerciseStarlarkTestFile
	thread := testSetup(t, nil)
	thread.Load = func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
		if module == "assert.star" {
			return starlarktest.LoadAssertModule()
		} else {
			return loader(thread, module)
		}
	}
	dir := dataDir()
	thread.SetLocal(callerDirKey, dir)
	LoadPathRoot = filepath.Dir(dir)
	if _, err := starlark.ExecFile(thread, "load.star", nil, builtins); err != nil {
		if err, ok := err.(*starlark.EvalError); ok {
			t.Fatal(err.Backtrace())
		}
		t.Fatal(err)
	}
}

func TestRegex(t *testing.T) {
	exerciseStarlarkTestFile(t, "testdata/regex.star")
}

func TestShell(t *testing.T) {
	if err := os.Setenv("TEST_DATA_DIR", dataDir()); err != nil {
		t.Fatal(err)
	}
	exerciseStarlarkTestFile(t, "testdata/shell.star")
}
