package initwd

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"github.com/go-test/deep"
	"github.com/google/go-cmp/cmp"
	version "github.com/hashicorp/go-version"
	svchost "github.com/hashicorp/terraform-svchost"
	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/configs/configload"
	"github.com/hashicorp/terraform/internal/copy"
	"github.com/hashicorp/terraform/internal/registry"
	"github.com/hashicorp/terraform/internal/tfdiags"

	_ "github.com/hashicorp/terraform/internal/logging"
)

func TestMain(m *testing.M) {
	flag.Parse()
	os.Exit(m.Run())
}

func TestModuleInstaller(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/local-modules")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)
	assertNoDiagnostics(t, diags)

	wantCalls := []testInstallHookCall{
		{
			Name:        "Install",
			ModuleAddr:  "child_a",
			PackageAddr: "",
			LocalPath:   "child_a",
		},
		{
			Name:        "Install",
			ModuleAddr:  "child_a.child_b",
			PackageAddr: "",
			LocalPath:   "child_a/child_b",
		},
	}

	if assertResultDeepEqual(t, hooks.Calls, wantCalls) {
		return
	}

	loader, err := configload.NewLoader(&configload.Config{
		ModulesDir: modulesDir,
	})
	if err != nil {
		t.Fatal(err)
	}

	// Make sure the configuration is loadable now.
	// (This ensures that correct information is recorded in the manifest.)
	config, loadDiags := loader.LoadConfig(".")
	assertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags))

	wantTraces := map[string]string{
		"":                "in root module",
		"child_a":         "in child_a module",
		"child_a.child_b": "in child_b module",
	}
	gotTraces := map[string]string{}
	config.DeepEach(func(c *configs.Config) {
		path := strings.Join(c.Path, ".")
		if c.Module.Variables["v"] == nil {
			gotTraces[path] = "<missing>"
			return
		}
		varDesc := c.Module.Variables["v"].Description
		gotTraces[path] = varDesc
	})
	assertResultDeepEqual(t, gotTraces, wantTraces)
}

func TestModuleInstaller_error(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/local-module-error")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if !diags.HasErrors() {
		t.Fatal("expected error")
	} else {
		assertDiagnosticSummary(t, diags, "Invalid module source address")
	}
}

func TestModuleInstaller_packageEscapeError(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/load-module-package-escape")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	// For this particular test we need an absolute path in the root module
	// that must actually resolve to our temporary directory in "dir", so
	// we need to do a little rewriting. We replace the arbitrary placeholder
	// %%BASE%% with the temporary directory path.
	{
		rootFilename := filepath.Join(dir, "package-escape.tf")
		template, err := ioutil.ReadFile(rootFilename)
		if err != nil {
			t.Fatal(err)
		}
		final := bytes.ReplaceAll(template, []byte("%%BASE%%"), []byte(filepath.ToSlash(dir)))
		err = ioutil.WriteFile(rootFilename, final, 0644)
		if err != nil {
			t.Fatal(err)
		}
	}

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if !diags.HasErrors() {
		t.Fatal("expected error")
	} else {
		assertDiagnosticSummary(t, diags, "Local module path escapes module package")
	}
}

func TestModuleInstaller_explicitPackageBoundary(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/load-module-package-prefix")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	// For this particular test we need an absolute path in the root module
	// that must actually resolve to our temporary directory in "dir", so
	// we need to do a little rewriting. We replace the arbitrary placeholder
	// %%BASE%% with the temporary directory path.
	{
		rootFilename := filepath.Join(dir, "package-prefix.tf")
		template, err := ioutil.ReadFile(rootFilename)
		if err != nil {
			t.Fatal(err)
		}
		final := bytes.ReplaceAll(template, []byte("%%BASE%%"), []byte(filepath.ToSlash(dir)))
		err = ioutil.WriteFile(rootFilename, final, 0644)
		if err != nil {
			t.Fatal(err)
		}
	}

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if diags.HasErrors() {
		t.Fatalf("unexpected errors\n%s", diags.Err().Error())
	}
}

func TestModuleInstaller_ExactMatchPrerelease(t *testing.T) {
	if os.Getenv("TF_ACC") == "" {
		t.Skip("this test accesses registry.terraform.io and github.com; set TF_ACC=1 to run it")
	}

	fixtureDir := filepath.Clean("testdata/prerelease-version-constraint-match")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, registry.NewClient(nil, nil))
	cfg, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if diags.HasErrors() {
		t.Fatalf("found unexpected errors: %s", diags.Err())
	}

	if !cfg.Children["acctest_exact"].Version.Equal(version.Must(version.NewVersion("v0.0.3-alpha.1"))) {
		t.Fatalf("expected version %s but found version %s", "v0.0.3-alpha.1", cfg.Version.String())
	}
}

func TestModuleInstaller_PartialMatchPrerelease(t *testing.T) {
	if os.Getenv("TF_ACC") == "" {
		t.Skip("this test accesses registry.terraform.io and github.com; set TF_ACC=1 to run it")
	}

	fixtureDir := filepath.Clean("testdata/prerelease-version-constraint")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, registry.NewClient(nil, nil))
	cfg, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if diags.HasErrors() {
		t.Fatalf("found unexpected errors: %s", diags.Err())
	}

	if !cfg.Children["acctest_partial"].Version.Equal(version.Must(version.NewVersion("v0.0.2"))) {
		t.Fatalf("expected version %s but found version %s", "v0.0.2", cfg.Version.String())
	}
}

func TestModuleInstaller_invalid_version_constraint_error(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/invalid-version-constraint")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if !diags.HasErrors() {
		t.Fatal("expected error")
	} else {
		// We use the presence of the "version" argument as a heuristic for
		// user intent to use a registry module, and so we intentionally catch
		// this as an invalid registry module address rather than an invalid
		// version constraint, so we can surface the specific address parsing
		// error instead of a generic version constraint error.
		assertDiagnosticSummary(t, diags, "Invalid registry module source address")
	}
}

func TestModuleInstaller_invalidVersionConstraintGetter(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/invalid-version-constraint")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if !diags.HasErrors() {
		t.Fatal("expected error")
	} else {
		// We use the presence of the "version" argument as a heuristic for
		// user intent to use a registry module, and so we intentionally catch
		// this as an invalid registry module address rather than an invalid
		// version constraint, so we can surface the specific address parsing
		// error instead of a generic version constraint error.
		assertDiagnosticSummary(t, diags, "Invalid registry module source address")
	}
}

func TestModuleInstaller_invalidVersionConstraintLocal(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/invalid-version-constraint-local")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

	if !diags.HasErrors() {
		t.Fatal("expected error")
	} else {
		// We use the presence of the "version" argument as a heuristic for
		// user intent to use a registry module, and so we intentionally catch
		// this as an invalid registry module address rather than an invalid
		// version constraint, so we can surface the specific address parsing
		// error instead of a generic version constraint error.
		assertDiagnosticSummary(t, diags, "Invalid registry module source address")
	}
}

func TestModuleInstaller_symlink(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/local-module-symlink")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)
	assertNoDiagnostics(t, diags)

	wantCalls := []testInstallHookCall{
		{
			Name:        "Install",
			ModuleAddr:  "child_a",
			PackageAddr: "",
			LocalPath:   "child_a",
		},
		{
			Name:        "Install",
			ModuleAddr:  "child_a.child_b",
			PackageAddr: "",
			LocalPath:   "child_a/child_b",
		},
	}

	if assertResultDeepEqual(t, hooks.Calls, wantCalls) {
		return
	}

	loader, err := configload.NewLoader(&configload.Config{
		ModulesDir: modulesDir,
	})
	if err != nil {
		t.Fatal(err)
	}

	// Make sure the configuration is loadable now.
	// (This ensures that correct information is recorded in the manifest.)
	config, loadDiags := loader.LoadConfig(".")
	assertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags))

	wantTraces := map[string]string{
		"":                "in root module",
		"child_a":         "in child_a module",
		"child_a.child_b": "in child_b module",
	}
	gotTraces := map[string]string{}
	config.DeepEach(func(c *configs.Config) {
		path := strings.Join(c.Path, ".")
		if c.Module.Variables["v"] == nil {
			gotTraces[path] = "<missing>"
			return
		}
		varDesc := c.Module.Variables["v"].Description
		gotTraces[path] = varDesc
	})
	assertResultDeepEqual(t, gotTraces, wantTraces)
}

func TestLoaderInstallModules_registry(t *testing.T) {
	if os.Getenv("TF_ACC") == "" {
		t.Skip("this test accesses registry.terraform.io and github.com; set TF_ACC=1 to run it")
	}

	fixtureDir := filepath.Clean("testdata/registry-modules")
	tmpDir, done := tempChdir(t, fixtureDir)
	// the module installer runs filepath.EvalSymlinks() on the destination
	// directory before copying files, and the resultant directory is what is
	// returned by the install hooks. Without this, tests could fail on machines
	// where the default temp dir was a symlink.
	dir, err := filepath.EvalSymlinks(tmpDir)
	if err != nil {
		t.Error(err)
	}

	defer done()

	hooks := &testInstallHooks{}
	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, registry.NewClient(nil, nil))
	_, diags := inst.InstallModules(context.Background(), dir, false, hooks)
	assertNoDiagnostics(t, diags)

	v := version.Must(version.NewVersion("0.0.1"))

	wantCalls := []testInstallHookCall{
		// the configuration builder visits each level of calls in lexicographical
		// order by name, so the following list is kept in the same order.

		// acctest_child_a accesses //modules/child_a directly
		{
			Name:        "Download",
			ModuleAddr:  "acctest_child_a",
			PackageAddr: "registry.terraform.io/hashicorp/module-installer-acctest/aws", // intentionally excludes the subdir because we're downloading the whole package here
			Version:     v,
		},
		{
			Name:       "Install",
			ModuleAddr: "acctest_child_a",
			Version:    v,
			// NOTE: This local path and the other paths derived from it below
			// can vary depending on how the registry is implemented. At the
			// time of writing this test, registry.terraform.io returns
			// git repository source addresses and so this path refers to the
			// root of the git clone, but historically the registry referred
			// to GitHub-provided tar archives which meant that there was an
			// extra level of subdirectory here for the typical directory
			// nesting in tar archives, which would've been reflected as
			// an extra segment on this path. If this test fails due to an
			// additional path segment in future, then a change to the upstream
			// registry might be the root cause.
			LocalPath: filepath.Join(dir, ".terraform/modules/acctest_child_a/modules/child_a"),
		},

		// acctest_child_a.child_b
		// (no download because it's a relative path inside acctest_child_a)
		{
			Name:       "Install",
			ModuleAddr: "acctest_child_a.child_b",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_child_a/modules/child_b"),
		},

		// acctest_child_b accesses //modules/child_b directly
		{
			Name:        "Download",
			ModuleAddr:  "acctest_child_b",
			PackageAddr: "registry.terraform.io/hashicorp/module-installer-acctest/aws", // intentionally excludes the subdir because we're downloading the whole package here
			Version:     v,
		},
		{
			Name:       "Install",
			ModuleAddr: "acctest_child_b",
			Version:    v,
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_child_b/modules/child_b"),
		},

		// acctest_root
		{
			Name:        "Download",
			ModuleAddr:  "acctest_root",
			PackageAddr: "registry.terraform.io/hashicorp/module-installer-acctest/aws",
			Version:     v,
		},
		{
			Name:       "Install",
			ModuleAddr: "acctest_root",
			Version:    v,
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_root"),
		},

		// acctest_root.child_a
		// (no download because it's a relative path inside acctest_root)
		{
			Name:       "Install",
			ModuleAddr: "acctest_root.child_a",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_root/modules/child_a"),
		},

		// acctest_root.child_a.child_b
		// (no download because it's a relative path inside acctest_root, via acctest_root.child_a)
		{
			Name:       "Install",
			ModuleAddr: "acctest_root.child_a.child_b",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_root/modules/child_b"),
		},
	}

	if diff := cmp.Diff(wantCalls, hooks.Calls); diff != "" {
		t.Fatalf("wrong installer calls\n%s", diff)
	}

	//check that the registry reponses were cached
	packageAddr := addrs.ModuleRegistryPackage{
		Host:         svchost.Hostname("registry.terraform.io"),
		Namespace:    "hashicorp",
		Name:         "module-installer-acctest",
		TargetSystem: "aws",
	}
	if _, ok := inst.registryPackageVersions[packageAddr]; !ok {
		t.Errorf("module versions cache was not populated\ngot: %s\nwant: key hashicorp/module-installer-acctest/aws", spew.Sdump(inst.registryPackageVersions))
	}
	if _, ok := inst.registryPackageSources[moduleVersion{module: packageAddr, version: "0.0.1"}]; !ok {
		t.Errorf("module download url cache was not populated\ngot: %s", spew.Sdump(inst.registryPackageSources))
	}

	loader, err := configload.NewLoader(&configload.Config{
		ModulesDir: modulesDir,
	})
	if err != nil {
		t.Fatal(err)
	}

	// Make sure the configuration is loadable now.
	// (This ensures that correct information is recorded in the manifest.)
	config, loadDiags := loader.LoadConfig(".")
	assertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags))

	wantTraces := map[string]string{
		"":                             "in local caller for registry-modules",
		"acctest_root":                 "in root module",
		"acctest_root.child_a":         "in child_a module",
		"acctest_root.child_a.child_b": "in child_b module",
		"acctest_child_a":              "in child_a module",
		"acctest_child_a.child_b":      "in child_b module",
		"acctest_child_b":              "in child_b module",
	}
	gotTraces := map[string]string{}
	config.DeepEach(func(c *configs.Config) {
		path := strings.Join(c.Path, ".")
		if c.Module.Variables["v"] == nil {
			gotTraces[path] = "<missing>"
			return
		}
		varDesc := c.Module.Variables["v"].Description
		gotTraces[path] = varDesc
	})
	assertResultDeepEqual(t, gotTraces, wantTraces)

}

func TestLoaderInstallModules_goGetter(t *testing.T) {
	if os.Getenv("TF_ACC") == "" {
		t.Skip("this test accesses github.com; set TF_ACC=1 to run it")
	}

	fixtureDir := filepath.Clean("testdata/go-getter-modules")
	tmpDir, done := tempChdir(t, fixtureDir)
	// the module installer runs filepath.EvalSymlinks() on the destination
	// directory before copying files, and the resultant directory is what is
	// returned by the install hooks. Without this, tests could fail on machines
	// where the default temp dir was a symlink.
	dir, err := filepath.EvalSymlinks(tmpDir)
	if err != nil {
		t.Error(err)
	}
	defer done()

	hooks := &testInstallHooks{}
	modulesDir := filepath.Join(dir, ".terraform/modules")
	inst := NewModuleInstaller(modulesDir, registry.NewClient(nil, nil))
	_, diags := inst.InstallModules(context.Background(), dir, false, hooks)
	assertNoDiagnostics(t, diags)

	wantCalls := []testInstallHookCall{
		// the configuration builder visits each level of calls in lexicographical
		// order by name, so the following list is kept in the same order.

		// acctest_child_a accesses //modules/child_a directly
		{
			Name:        "Download",
			ModuleAddr:  "acctest_child_a",
			PackageAddr: "git::https://github.com/hashicorp/terraform-aws-module-installer-acctest.git?ref=v0.0.1", // intentionally excludes the subdir because we're downloading the whole repo here
		},
		{
			Name:       "Install",
			ModuleAddr: "acctest_child_a",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_child_a/modules/child_a"),
		},

		// acctest_child_a.child_b
		// (no download because it's a relative path inside acctest_child_a)
		{
			Name:       "Install",
			ModuleAddr: "acctest_child_a.child_b",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_child_a/modules/child_b"),
		},

		// acctest_child_b accesses //modules/child_b directly
		{
			Name:        "Download",
			ModuleAddr:  "acctest_child_b",
			PackageAddr: "git::https://github.com/hashicorp/terraform-aws-module-installer-acctest.git?ref=v0.0.1", // intentionally excludes the subdir because we're downloading the whole package here
		},
		{
			Name:       "Install",
			ModuleAddr: "acctest_child_b",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_child_b/modules/child_b"),
		},

		// acctest_root
		{
			Name:        "Download",
			ModuleAddr:  "acctest_root",
			PackageAddr: "git::https://github.com/hashicorp/terraform-aws-module-installer-acctest.git?ref=v0.0.1",
		},
		{
			Name:       "Install",
			ModuleAddr: "acctest_root",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_root"),
		},

		// acctest_root.child_a
		// (no download because it's a relative path inside acctest_root)
		{
			Name:       "Install",
			ModuleAddr: "acctest_root.child_a",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_root/modules/child_a"),
		},

		// acctest_root.child_a.child_b
		// (no download because it's a relative path inside acctest_root, via acctest_root.child_a)
		{
			Name:       "Install",
			ModuleAddr: "acctest_root.child_a.child_b",
			LocalPath:  filepath.Join(dir, ".terraform/modules/acctest_root/modules/child_b"),
		},
	}

	if diff := cmp.Diff(wantCalls, hooks.Calls); diff != "" {
		t.Fatalf("wrong installer calls\n%s", diff)
	}

	loader, err := configload.NewLoader(&configload.Config{
		ModulesDir: modulesDir,
	})
	if err != nil {
		t.Fatal(err)
	}

	// Make sure the configuration is loadable now.
	// (This ensures that correct information is recorded in the manifest.)
	config, loadDiags := loader.LoadConfig(".")
	assertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags))

	wantTraces := map[string]string{
		"":                             "in local caller for go-getter-modules",
		"acctest_root":                 "in root module",
		"acctest_root.child_a":         "in child_a module",
		"acctest_root.child_a.child_b": "in child_b module",
		"acctest_child_a":              "in child_a module",
		"acctest_child_a.child_b":      "in child_b module",
		"acctest_child_b":              "in child_b module",
	}
	gotTraces := map[string]string{}
	config.DeepEach(func(c *configs.Config) {
		path := strings.Join(c.Path, ".")
		if c.Module.Variables["v"] == nil {
			gotTraces[path] = "<missing>"
			return
		}
		varDesc := c.Module.Variables["v"].Description
		gotTraces[path] = varDesc
	})
	assertResultDeepEqual(t, gotTraces, wantTraces)

}

type testInstallHooks struct {
	Calls []testInstallHookCall
}

type testInstallHookCall struct {
	Name        string
	ModuleAddr  string
	PackageAddr string
	Version     *version.Version
	LocalPath   string
}

func (h *testInstallHooks) Download(moduleAddr, packageAddr string, version *version.Version) {
	h.Calls = append(h.Calls, testInstallHookCall{
		Name:        "Download",
		ModuleAddr:  moduleAddr,
		PackageAddr: packageAddr,
		Version:     version,
	})
}

func (h *testInstallHooks) Install(moduleAddr string, version *version.Version, localPath string) {
	h.Calls = append(h.Calls, testInstallHookCall{
		Name:       "Install",
		ModuleAddr: moduleAddr,
		Version:    version,
		LocalPath:  localPath,
	})
}

// tempChdir copies the contents of the given directory to a temporary
// directory and changes the test process's current working directory to
// point to that directory. Also returned is a function that should be
// called at the end of the test (e.g. via "defer") to restore the previous
// working directory.
//
// Tests using this helper cannot safely be run in parallel with other tests.
func tempChdir(t *testing.T, sourceDir string) (string, func()) {
	t.Helper()

	tmpDir, err := ioutil.TempDir("", "terraform-configload")
	if err != nil {
		t.Fatalf("failed to create temporary directory: %s", err)
		return "", nil
	}

	if err := copy.CopyDir(tmpDir, sourceDir); err != nil {
		t.Fatalf("failed to copy fixture to temporary directory: %s", err)
		return "", nil
	}

	oldDir, err := os.Getwd()
	if err != nil {
		t.Fatalf("failed to determine current working directory: %s", err)
		return "", nil
	}

	err = os.Chdir(tmpDir)
	if err != nil {
		t.Fatalf("failed to switch to temp dir %s: %s", tmpDir, err)
		return "", nil
	}

	// Most of the tests need this, so we'll make it just in case.
	os.MkdirAll(filepath.Join(tmpDir, ".terraform/modules"), os.ModePerm)

	t.Logf("tempChdir switched to %s after copying from %s", tmpDir, sourceDir)

	return tmpDir, func() {
		err := os.Chdir(oldDir)
		if err != nil {
			panic(fmt.Errorf("failed to restore previous working directory %s: %s", oldDir, err))
		}

		if os.Getenv("TF_CONFIGLOAD_TEST_KEEP_TMP") == "" {
			os.RemoveAll(tmpDir)
		}
	}
}

func assertNoDiagnostics(t *testing.T, diags tfdiags.Diagnostics) bool {
	t.Helper()
	return assertDiagnosticCount(t, diags, 0)
}

func assertDiagnosticCount(t *testing.T, diags tfdiags.Diagnostics, want int) bool {
	t.Helper()
	if len(diags) != 0 {
		t.Errorf("wrong number of diagnostics %d; want %d", len(diags), want)
		for _, diag := range diags {
			t.Logf("- %#v", diag)
		}
		return true
	}
	return false
}

func assertDiagnosticSummary(t *testing.T, diags tfdiags.Diagnostics, want string) bool {
	t.Helper()

	for _, diag := range diags {
		if diag.Description().Summary == want {
			return false
		}
	}

	t.Errorf("missing diagnostic summary %q", want)
	for _, diag := range diags {
		t.Logf("- %#v", diag)
	}
	return true
}

func assertResultDeepEqual(t *testing.T, got, want interface{}) bool {
	t.Helper()
	if diff := deep.Equal(got, want); diff != nil {
		for _, problem := range diff {
			t.Errorf("%s", problem)
		}
		return true
	}
	return false
}
