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

package configs

import (
	"strings"
	"testing"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/zclconf/go-cty/cty"
)

// TestNewModule_provider_fqns exercises module.gatherProviderLocalNames()
func TestNewModule_provider_local_name(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/providers-explicit-fqn")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	p := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "foo", "test")
	if name, exists := mod.ProviderLocalNames[p]; !exists {
		t.Fatal("provider FQN foo/test not found")
	} else {
		if name != "foo-test" {
			t.Fatalf("provider localname mismatch: got %s, want foo-test", name)
		}
	}

	// ensure the reverse lookup (fqn to local name) works as well
	localName := mod.LocalNameForProvider(p)
	if localName != "foo-test" {
		t.Fatal("provider local name not found")
	}

	// if there is not a local name for a provider, it should return the type name
	localName = mod.LocalNameForProvider(addrs.NewDefaultProvider("nonexist"))
	if localName != "nonexist" {
		t.Error("wrong local name returned for a non-local provider")
	}

	// can also look up the "terraform" provider and see that it sources is
	// allowed to be overridden, even though there is a builtin provider
	// called "terraform".
	p = addrs.NewProvider(addrs.DefaultProviderRegistryHost, "not-builtin", "not-terraform")
	if name, exists := mod.ProviderLocalNames[p]; !exists {
		t.Fatal("provider FQN not-builtin/not-terraform not found")
	} else {
		if name != "terraform" {
			t.Fatalf("provider localname mismatch: got %s, want terraform", name)
		}
	}
}

// This test validates the provider FQNs set in each Resource
func TestNewModule_resource_providers(t *testing.T) {
	cfg, diags := testNestedModuleConfigFromDir(t, "testdata/valid-modules/nested-providers-fqns")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	// both the root and child module have two resources, one which should use
	// the default implied provider and one explicitly using a provider set in
	// required_providers
	wantImplicit := addrs.NewDefaultProvider("test")
	wantFoo := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "foo", "test")
	wantBar := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "bar", "test")

	// root module
	if !cfg.Module.ManagedResources["test_instance.explicit"].Provider.Equals(wantFoo) {
		t.Fatalf("wrong provider for \"test_instance.explicit\"\ngot:  %s\nwant: %s",
			cfg.Module.ManagedResources["test_instance.explicit"].Provider,
			wantFoo,
		)
	}
	if !cfg.Module.ManagedResources["test_instance.implicit"].Provider.Equals(wantImplicit) {
		t.Fatalf("wrong provider for \"test_instance.implicit\"\ngot:  %s\nwant: %s",
			cfg.Module.ManagedResources["test_instance.implicit"].Provider,
			wantImplicit,
		)
	}

	// a data source
	if !cfg.Module.DataResources["data.test_resource.explicit"].Provider.Equals(wantFoo) {
		t.Fatalf("wrong provider for \"module.child.test_instance.explicit\"\ngot:  %s\nwant: %s",
			cfg.Module.ManagedResources["test_instance.explicit"].Provider,
			wantBar,
		)
	}

	// child module
	cm := cfg.Children["child"].Module
	if !cm.ManagedResources["test_instance.explicit"].Provider.Equals(wantBar) {
		t.Fatalf("wrong provider for \"module.child.test_instance.explicit\"\ngot:  %s\nwant: %s",
			cfg.Module.ManagedResources["test_instance.explicit"].Provider,
			wantBar,
		)
	}
	if !cm.ManagedResources["test_instance.implicit"].Provider.Equals(wantImplicit) {
		t.Fatalf("wrong provider for \"module.child.test_instance.implicit\"\ngot:  %s\nwant: %s",
			cfg.Module.ManagedResources["test_instance.implicit"].Provider,
			wantImplicit,
		)
	}
}

func TestProviderForLocalConfig(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/providers-explicit-fqn")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}
	lc := addrs.LocalProviderConfig{LocalName: "foo-test"}
	got := mod.ProviderForLocalConfig(lc)
	want := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "foo", "test")
	if !got.Equals(want) {
		t.Fatalf("wrong result! got %#v, want %#v\n", got, want)
	}
}

// At most one required_providers block per module is permitted.
func TestModule_required_providers_multiple(t *testing.T) {
	_, diags := testModuleFromDir("testdata/invalid-modules/multiple-required-providers")
	if !diags.HasErrors() {
		t.Fatal("module should have error diags, but does not")
	}

	want := `Duplicate required providers configuration`
	if got := diags.Error(); !strings.Contains(got, want) {
		t.Fatalf("expected error to contain %q\nerror was:\n%s", want, got)
	}
}

// A module may have required_providers configured in files loaded later than
// resources. These provider settings should still be reflected in the
// resources' configuration.
func TestModule_required_providers_after_resource(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/required-providers-after-resource")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	want := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "foo", "test")

	req, exists := mod.ProviderRequirements.RequiredProviders["test"]
	if !exists {
		t.Fatal("no provider requirements found for \"test\"")
	}
	if req.Type != want {
		t.Errorf("wrong provider addr for \"test\"\ngot:  %s\nwant: %s",
			req.Type, want,
		)
	}

	if got := mod.ManagedResources["test_instance.my-instance"].Provider; !got.Equals(want) {
		t.Errorf("wrong provider addr for \"test_instance.my-instance\"\ngot:  %s\nwant: %s",
			got, want,
		)
	}
}

// We support overrides for required_providers blocks, which should replace the
// entire block for each provider localname, leaving other blocks unaffected.
// This should also be reflected in any resources in the module using this
// provider.
func TestModule_required_provider_overrides(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/required-providers-overrides")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	// The foo provider and resource should be unaffected
	want := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "acme", "foo")
	req, exists := mod.ProviderRequirements.RequiredProviders["foo"]
	if !exists {
		t.Fatal("no provider requirements found for \"foo\"")
	}
	if req.Type != want {
		t.Errorf("wrong provider addr for \"foo\"\ngot:  %s\nwant: %s",
			req.Type, want,
		)
	}
	if got := mod.ManagedResources["foo_thing.ft"].Provider; !got.Equals(want) {
		t.Errorf("wrong provider addr for \"foo_thing.ft\"\ngot:  %s\nwant: %s",
			got, want,
		)
	}

	// The bar provider and resource should be using the override config
	want = addrs.NewProvider(addrs.DefaultProviderRegistryHost, "blorp", "bar")
	req, exists = mod.ProviderRequirements.RequiredProviders["bar"]
	if !exists {
		t.Fatal("no provider requirements found for \"bar\"")
	}
	if req.Type != want {
		t.Errorf("wrong provider addr for \"bar\"\ngot:  %s\nwant: %s",
			req.Type, want,
		)
	}
	if gotVer, wantVer := req.Requirement.Required.String(), "~>2.0.0"; gotVer != wantVer {
		t.Errorf("wrong provider version constraint for \"bar\"\ngot:  %s\nwant: %s",
			gotVer, wantVer,
		)
	}
	if got := mod.ManagedResources["bar_thing.bt"].Provider; !got.Equals(want) {
		t.Errorf("wrong provider addr for \"bar_thing.bt\"\ngot:  %s\nwant: %s",
			got, want,
		)
	}
}

// Resources without explicit provider configuration are assigned a provider
// implied based on the resource type. For example, this resource:
//
//	resource "foo_instance" "test" {}
//
// ...is assigned to whichever provider has local name "foo" in the current
// module.
//
// To find the correct provider, we first look in the module's provider
// requirements map for a local name matching the resource type, and fall back
// to a default provider if none is found. This applies to both managed and
// data resources.
func TestModule_implied_provider(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/implied-providers")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	// The three providers used in the config resources
	foo := addrs.NewProvider("registry.acme.corp", "acme", "foo")
	whatever := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "acme", "something")
	bar := addrs.NewDefaultProvider("bar")

	// Verify that the registry.acme.corp/acme/foo provider is defined in the
	// module provider requirements with local name "foo"
	req, exists := mod.ProviderRequirements.RequiredProviders["foo"]
	if !exists {
		t.Fatal("no provider requirements found for \"foo\"")
	}
	if req.Type != foo {
		t.Errorf("wrong provider addr for \"foo\"\ngot:  %s\nwant: %s",
			req.Type, foo,
		)
	}

	// Verify that the acme/something provider is defined in the
	// module provider requirements with local name "whatever"
	req, exists = mod.ProviderRequirements.RequiredProviders["whatever"]
	if !exists {
		t.Fatal("no provider requirements found for \"foo\"")
	}
	if req.Type != whatever {
		t.Errorf("wrong provider addr for \"whatever\"\ngot:  %s\nwant: %s",
			req.Type, whatever,
		)
	}

	// Check that resources are assigned the correct providers: foo_* resources
	// should have the custom foo provider, bar_* resources the default bar
	// provider.
	tests := []struct {
		Address  string
		Provider addrs.Provider
	}{
		{"foo_resource.a", foo},
		{"data.foo_resource.b", foo},
		{"bar_resource.c", bar},
		{"data.bar_resource.d", bar},
		{"whatever_resource.e", whatever},
		{"data.whatever_resource.f", whatever},
	}
	for _, test := range tests {
		resources := mod.ManagedResources
		if strings.HasPrefix(test.Address, "data.") {
			resources = mod.DataResources
		}
		resource, exists := resources[test.Address]
		if !exists {
			t.Errorf("could not find resource %q in %#v", test.Address, resources)
			continue
		}
		if got := resource.Provider; !got.Equals(test.Provider) {
			t.Errorf("wrong provider addr for %q\ngot:  %s\nwant: %s",
				test.Address, got, test.Provider,
			)
		}
	}
}

func TestImpliedProviderForUnqualifiedType(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/implied-providers")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	foo := addrs.NewProvider("registry.acme.corp", "acme", "foo")
	whatever := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "acme", "something")
	bar := addrs.NewDefaultProvider("bar")
	tf := addrs.NewBuiltInProvider("terraform")

	tests := []struct {
		Type     string
		Provider addrs.Provider
	}{
		{"foo", foo},
		{"whatever", whatever},
		{"bar", bar},
		{"terraform", tf},
	}
	for _, test := range tests {
		got := mod.ImpliedProviderForUnqualifiedType(test.Type)
		if !got.Equals(test.Provider) {
			t.Errorf("wrong result for %q: got %#v, want %#v\n", test.Type, got, test.Provider)
		}
	}
}

func TestModule_backend_override(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/override-backend")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	gotType := mod.Backend.Type
	wantType := "bar"

	if gotType != wantType {
		t.Errorf("wrong result for backend type: got %#v, want %#v\n", gotType, wantType)
	}

	attrs, _ := mod.Backend.Config.JustAttributes()

	gotAttr, diags := attrs["path"].Expr.Value(nil)
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	wantAttr := cty.StringVal("CHANGED/relative/path/to/terraform.tfstate")

	if !gotAttr.RawEquals(wantAttr) {
		t.Errorf("wrong result for backend 'path': got %#v, want %#v\n", gotAttr, wantAttr)
	}
}

// Unlike most other overrides, backend blocks do not require a base configuration in a primary
// configuration file, as an omitted backend there implies the local backend.
func TestModule_backend_override_no_base(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/override-backend-no-base")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	if mod.Backend == nil {
		t.Errorf("expected module Backend not to be nil")
	}
}

func TestModule_cloud_override_backend(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/override-backend-with-cloud")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	if mod.Backend != nil {
		t.Errorf("expected module Backend to be nil")
	}

	if mod.CloudConfig == nil {
		t.Errorf("expected module CloudConfig not to be nil")
	}
}

// Unlike most other overrides, cloud blocks do not require a base configuration in a primary
// configuration file, as an omitted backend there implies the local backend and cloud blocks
// override backends.
func TestModule_cloud_override_no_base(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/override-cloud-no-base")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	if mod.CloudConfig == nil {
		t.Errorf("expected module CloudConfig not to be nil")
	}
}

func TestModule_cloud_override(t *testing.T) {
	mod, diags := testModuleFromDir("testdata/valid-modules/override-cloud")
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	attrs, _ := mod.CloudConfig.Config.JustAttributes()

	gotAttr, diags := attrs["organization"].Expr.Value(nil)
	if diags.HasErrors() {
		t.Fatal(diags.Error())
	}

	wantAttr := cty.StringVal("CHANGED")

	if !gotAttr.RawEquals(wantAttr) {
		t.Errorf("wrong result for Cloud 'organization': got %#v, want %#v\n", gotAttr, wantAttr)
	}

	// The override should have completely replaced the cloud block in the primary file, no merging
	if attrs["should_not_be_present_with_override"] != nil {
		t.Errorf("expected 'should_not_be_present_with_override' attribute to be nil")
	}
}

func TestModule_cloud_duplicate_overrides(t *testing.T) {
	_, diags := testModuleFromDir("testdata/invalid-modules/override-cloud-duplicates")
	want := `Duplicate Terraform Cloud configurations`
	if got := diags.Error(); !strings.Contains(got, want) {
		t.Fatalf("expected module error to contain %q\nerror was:\n%s", want, got)
	}
}
