// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

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")
	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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_emptyModuleName(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/empty-module-name")
	dir, done := tempChdir(t, fixtureDir)
	defer done()

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, nil)
	_, diags := inst.InstallModules(context.Background(), ".", false, hooks)

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

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

	hooks := &testInstallHooks{}

	modulesDir := filepath.Join(dir, ".terraform/modules")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil))
	_, diags := inst.InstallModules(context.Background(), dir, false, hooks)

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

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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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")

	loader, close := configload.NewLoaderForTests(t)
	defer close()
	inst := NewModuleInstaller(modulesDir, loader, 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
}
