package configload

import (
	"path/filepath"
	"reflect"
	"sort"
	"strings"
	"testing"

	"github.com/davecgh/go-spew/spew"
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/internal/configs"
)

func TestLoaderLoadConfig_okay(t *testing.T) {
	fixtureDir := filepath.Clean("testdata/already-installed")
	loader, err := NewLoader(&Config{
		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
	})
	if err != nil {
		t.Fatalf("unexpected error from NewLoader: %s", err)
	}

	cfg, diags := loader.LoadConfig(fixtureDir)
	assertNoDiagnostics(t, diags)
	if cfg == nil {
		t.Fatalf("config is nil; want non-nil")
	}

	var gotPaths []string
	cfg.DeepEach(func(c *configs.Config) {
		gotPaths = append(gotPaths, strings.Join(c.Path, "."))
	})
	sort.Strings(gotPaths)
	wantPaths := []string{
		"", // root module
		"child_a",
		"child_a.child_c",
		"child_b",
		"child_b.child_d",
	}

	if !reflect.DeepEqual(gotPaths, wantPaths) {
		t.Fatalf("wrong module paths\ngot: %swant %s", spew.Sdump(gotPaths), spew.Sdump(wantPaths))
	}

	t.Run("child_a.child_c output", func(t *testing.T) {
		output := cfg.Children["child_a"].Children["child_c"].Module.Outputs["hello"]
		got, diags := output.Expr.Value(nil)
		assertNoDiagnostics(t, diags)
		assertResultCtyEqual(t, got, cty.StringVal("Hello from child_c"))
	})
	t.Run("child_b.child_d output", func(t *testing.T) {
		output := cfg.Children["child_b"].Children["child_d"].Module.Outputs["hello"]
		got, diags := output.Expr.Value(nil)
		assertNoDiagnostics(t, diags)
		assertResultCtyEqual(t, got, cty.StringVal("Hello from child_d"))
	})
}

func TestLoaderLoadConfig_addVersion(t *testing.T) {
	// This test is for what happens when there is a version constraint added
	// to a module that previously didn't have one.
	fixtureDir := filepath.Clean("testdata/add-version-constraint")
	loader, err := NewLoader(&Config{
		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
	})
	if err != nil {
		t.Fatalf("unexpected error from NewLoader: %s", err)
	}

	_, diags := loader.LoadConfig(fixtureDir)
	if !diags.HasErrors() {
		t.Fatalf("success; want error")
	}
	got := diags.Error()
	want := "Module version requirements have changed"
	if !strings.Contains(got, want) {
		t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want)
	}
}

func TestLoaderLoadConfig_loadDiags(t *testing.T) {
	// building a config which didn't load correctly may cause configs to panic
	fixtureDir := filepath.Clean("testdata/invalid-names")
	loader, err := NewLoader(&Config{
		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
	})
	if err != nil {
		t.Fatalf("unexpected error from NewLoader: %s", err)
	}

	cfg, diags := loader.LoadConfig(fixtureDir)
	if !diags.HasErrors() {
		t.Fatal("success; want error")
	}

	if cfg == nil {
		t.Fatal("partial config not returned with diagnostics")
	}

	if cfg.Module == nil {
		t.Fatal("expected config module")
	}
}

func TestLoaderLoadConfig_loadDiagsFromSubmodules(t *testing.T) {
	// building a config which didn't load correctly may cause configs to panic
	fixtureDir := filepath.Clean("testdata/invalid-names-in-submodules")
	loader, err := NewLoader(&Config{
		ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
	})
	if err != nil {
		t.Fatalf("unexpected error from NewLoader: %s", err)
	}

	cfg, diags := loader.LoadConfig(fixtureDir)
	if !diags.HasErrors() {
		t.Fatalf("loading succeeded; want an error")
	}
	if got, want := diags.Error(), " Invalid provider local name"; !strings.Contains(got, want) {
		t.Errorf("missing expected error\nwant substring: %s\ngot: %s", want, got)
	}

	if cfg == nil {
		t.Fatal("partial config not returned with diagnostics")
	}

	if cfg.Module == nil {
		t.Fatal("expected config module")
	}
}

func TestLoaderLoadConfig_childProviderGrandchildCount(t *testing.T) {
	// This test is focused on the specific situation where:
	// - A child module contains a nested provider block, which is no longer
	//   recommended but supported for backward-compatibility.
	// - A child of that child does _not_ contain a nested provider block,
	//   and is called with "count" (would also apply to "for_each" and
	//   "depends_on").
	// It isn't valid to use "count" with a module that _itself_ contains
	// a provider configuration, but it _is_ valid for a module with a
	// provider configuration to call another module with count. We previously
	// botched this rule and so this is a regression test to cover the
	// solution to that mistake:
	//     https://github.com/hashicorp/terraform/issues/31081

	// Since this test is based on success rather than failure and it's
	// covering a relatively large set of code where only a small part
	// contributes to the test, we'll make sure to test both the success and
	// failure cases here so that we'll have a better chance of noticing if a
	// future change makes this succeed only because we've reorganized the code
	// so that the check isn't happening at all anymore.
	//
	// If the "not okay" subtest fails, you should also be skeptical about
	// whether the "okay" subtest is still valid, even if it happens to
	// still be passing.
	t.Run("okay", func(t *testing.T) {
		fixtureDir := filepath.Clean("testdata/child-provider-grandchild-count")
		loader, err := NewLoader(&Config{
			ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
		})
		if err != nil {
			t.Fatalf("unexpected error from NewLoader: %s", err)
		}

		cfg, diags := loader.LoadConfig(fixtureDir)
		assertNoDiagnostics(t, diags)
		if cfg == nil {
			t.Fatalf("config is nil; want non-nil")
		}

		var gotPaths []string
		cfg.DeepEach(func(c *configs.Config) {
			gotPaths = append(gotPaths, strings.Join(c.Path, "."))
		})
		sort.Strings(gotPaths)
		wantPaths := []string{
			"", // root module
			"child",
			"child.grandchild",
		}

		if !reflect.DeepEqual(gotPaths, wantPaths) {
			t.Fatalf("wrong module paths\ngot: %swant %s", spew.Sdump(gotPaths), spew.Sdump(wantPaths))
		}
	})
	t.Run("not okay", func(t *testing.T) {
		fixtureDir := filepath.Clean("testdata/child-provider-child-count")
		loader, err := NewLoader(&Config{
			ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"),
		})
		if err != nil {
			t.Fatalf("unexpected error from NewLoader: %s", err)
		}

		_, diags := loader.LoadConfig(fixtureDir)
		if !diags.HasErrors() {
			t.Fatalf("loading succeeded; want an error")
		}
		if got, want := diags.Error(), "Module is incompatible with count, for_each, and depends_on"; !strings.Contains(got, want) {
			t.Errorf("missing expected error\nwant substring: %s\ngot: %s", want, got)
		}
	})

}
