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

package terraform

import (
	"fmt"
	"strings"
	"testing"

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

func testProviderTransformerGraph(t *testing.T, cfg *configs.Config) *Graph {
	t.Helper()

	g := &Graph{Path: addrs.RootModuleInstance}
	ct := &ConfigTransformer{Config: cfg}
	if err := ct.Transform(g); err != nil {
		t.Fatal(err)
	}
	arct := &AttachResourceConfigTransformer{Config: cfg}
	if err := arct.Transform(g); err != nil {
		t.Fatal(err)
	}

	return g
}

func TestProviderTransformer(t *testing.T) {
	mod := testModule(t, "transform-provider-basic")

	g := testProviderTransformerGraph(t, mod)
	{
		transform := &MissingProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	transform := &ProviderTransformer{}
	if err := transform.Transform(g); err != nil {
		t.Fatalf("err: %s", err)
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformProviderBasicStr)
	if actual != expected {
		t.Fatalf("bad:\n\n%s", actual)
	}
}

// Test providers with FQNs that do not match the typeName
func TestProviderTransformer_fqns(t *testing.T) {
	for _, mod := range []string{"fqns", "fqns-module"} {
		mod := testModule(t, fmt.Sprintf("transform-provider-%s", mod))

		g := testProviderTransformerGraph(t, mod)
		{
			transform := &MissingProviderTransformer{Config: mod}
			if err := transform.Transform(g); err != nil {
				t.Fatalf("err: %s", err)
			}
		}

		transform := &ProviderTransformer{Config: mod}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}

		actual := strings.TrimSpace(g.String())
		expected := strings.TrimSpace(testTransformProviderBasicStr)
		if actual != expected {
			t.Fatalf("bad:\n\n%s", actual)
		}
	}
}

func TestCloseProviderTransformer(t *testing.T) {
	mod := testModule(t, "transform-provider-basic")
	g := testProviderTransformerGraph(t, mod)

	{
		transform := &MissingProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &ProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &CloseProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformCloseProviderBasicStr)
	if actual != expected {
		t.Fatalf("bad:\n\n%s", actual)
	}
}

func TestCloseProviderTransformer_withTargets(t *testing.T) {
	mod := testModule(t, "transform-provider-basic")

	g := testProviderTransformerGraph(t, mod)
	transforms := []GraphTransformer{
		&MissingProviderTransformer{},
		&ProviderTransformer{},
		&CloseProviderTransformer{},
		&TargetsTransformer{
			Targets: []addrs.Targetable{
				addrs.RootModuleInstance.Resource(
					addrs.ManagedResourceMode, "something", "else",
				),
			},
		},
	}

	for _, tr := range transforms {
		if err := tr.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(``)
	if actual != expected {
		t.Fatalf("expected:%s\n\ngot:\n\n%s", expected, actual)
	}
}

func TestMissingProviderTransformer(t *testing.T) {
	mod := testModule(t, "transform-provider-missing")

	g := testProviderTransformerGraph(t, mod)
	{
		transform := &MissingProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &ProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &CloseProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformMissingProviderBasicStr)
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

func TestMissingProviderTransformer_grandchildMissing(t *testing.T) {
	mod := testModule(t, "transform-provider-missing-grandchild")

	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }

	g := testProviderTransformerGraph(t, mod)
	{
		transform := transformProviders(concrete, mod)
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}
	{
		transform := &TransitiveReductionTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformMissingGrandchildProviderStr)
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

func TestPruneProviderTransformer(t *testing.T) {
	mod := testModule(t, "transform-provider-prune")

	g := testProviderTransformerGraph(t, mod)
	{
		transform := &MissingProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &ProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &CloseProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &PruneProviderTransformer{}
		if err := transform.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformPruneProviderBasicStr)
	if actual != expected {
		t.Fatalf("bad:\n\n%s", actual)
	}
}

// the child module resource is attached to the configured parent provider
func TestProviderConfigTransformer_parentProviders(t *testing.T) {
	mod := testModule(t, "transform-provider-inherit")
	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }

	g := testProviderTransformerGraph(t, mod)
	{
		tf := transformProviders(concrete, mod)
		if err := tf.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformModuleProviderConfigStr)
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

// the child module resource is attached to the configured grand-parent provider
func TestProviderConfigTransformer_grandparentProviders(t *testing.T) {
	mod := testModule(t, "transform-provider-grandchild-inherit")
	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }

	g := testProviderTransformerGraph(t, mod)
	{
		tf := transformProviders(concrete, mod)
		if err := tf.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformModuleProviderGrandparentStr)
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

func TestProviderConfigTransformer_inheritOldSkool(t *testing.T) {
	mod := testModuleInline(t, map[string]string{
		"main.tf": `
provider "test" {
  test_string = "config"
}

module "moda" {
  source = "./moda"
}
`,

		"moda/main.tf": `
resource "test_object" "a" {
}
`,
	})
	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }

	g := testProviderTransformerGraph(t, mod)
	{
		tf := transformProviders(concrete, mod)
		if err := tf.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	expected := `module.moda.test_object.a
  provider["registry.terraform.io/hashicorp/test"]
provider["registry.terraform.io/hashicorp/test"]`

	actual := strings.TrimSpace(g.String())
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

// Verify that configurations which are not recommended yet supported still work
func TestProviderConfigTransformer_nestedModuleProviders(t *testing.T) {
	mod := testModuleInline(t, map[string]string{
		"main.tf": `
terraform {
  required_providers {
    test = {
      source = "registry.terraform.io/hashicorp/test"
	}
  }
}

provider "test" {
  alias = "z"
  test_string = "config"
}

module "moda" {
  source = "./moda"
  providers = {
    test.x = test.z
  }
}
`,

		"moda/main.tf": `
terraform {
  required_providers {
    test = {
      source = "registry.terraform.io/hashicorp/test"
      configuration_aliases = [ test.x ]
	}
  }
}

provider "test" {
  test_string = "config"
}

// this should connect to this module's provider
resource "test_object" "a" {
}

resource "test_object" "x" {
  provider = test.x
}

module "modb" {
  source = "./modb"
}
`,

		"moda/modb/main.tf": `
# this should end up with the provider from the parent module
resource "test_object" "a" {
}
`,
	})
	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }

	g := testProviderTransformerGraph(t, mod)
	{
		tf := transformProviders(concrete, mod)
		if err := tf.Transform(g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	expected := `module.moda.module.modb.test_object.a
  module.moda.provider["registry.terraform.io/hashicorp/test"]
module.moda.provider["registry.terraform.io/hashicorp/test"]
module.moda.test_object.a
  module.moda.provider["registry.terraform.io/hashicorp/test"]
module.moda.test_object.x
  provider["registry.terraform.io/hashicorp/test"].z
provider["registry.terraform.io/hashicorp/test"].z`

	actual := strings.TrimSpace(g.String())
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

func TestProviderConfigTransformer_duplicateLocalName(t *testing.T) {
	mod := testModuleInline(t, map[string]string{
		"main.tf": `
terraform {
  required_providers {
	# We have to allow this since it wasn't previously prevented. If the
	# default config is equivalent to the provider config, the user may never
	# see an error.
    dupe = {
      source = "registry.terraform.io/hashicorp/test"
    }
  }
}

provider "test" {
}
`})
	concrete := func(a *NodeAbstractProvider) dag.Vertex { return a }

	g := testProviderTransformerGraph(t, mod)
	tf := ProviderConfigTransformer{
		Config:   mod,
		Concrete: concrete,
	}
	if err := tf.Transform(g); err != nil {
		t.Fatalf("err: %s", err)
	}

	expected := `provider["registry.terraform.io/hashicorp/test"]`

	actual := strings.TrimSpace(g.String())
	if actual != expected {
		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
	}
}

const testTransformProviderBasicStr = `
aws_instance.web
  provider["registry.terraform.io/hashicorp/aws"]
provider["registry.terraform.io/hashicorp/aws"]
`

const testTransformCloseProviderBasicStr = `
aws_instance.web
  provider["registry.terraform.io/hashicorp/aws"]
provider["registry.terraform.io/hashicorp/aws"]
provider["registry.terraform.io/hashicorp/aws"] (close)
  aws_instance.web
  provider["registry.terraform.io/hashicorp/aws"]
`

const testTransformMissingProviderBasicStr = `
aws_instance.web
  provider["registry.terraform.io/hashicorp/aws"]
foo_instance.web
  provider["registry.terraform.io/hashicorp/foo"]
provider["registry.terraform.io/hashicorp/aws"]
provider["registry.terraform.io/hashicorp/aws"] (close)
  aws_instance.web
  provider["registry.terraform.io/hashicorp/aws"]
provider["registry.terraform.io/hashicorp/foo"]
provider["registry.terraform.io/hashicorp/foo"] (close)
  foo_instance.web
  provider["registry.terraform.io/hashicorp/foo"]
`

const testTransformMissingGrandchildProviderStr = `
module.sub.module.subsub.bar_instance.two
  provider["registry.terraform.io/hashicorp/bar"]
module.sub.module.subsub.foo_instance.one
  module.sub.provider["registry.terraform.io/hashicorp/foo"]
module.sub.provider["registry.terraform.io/hashicorp/foo"]
provider["registry.terraform.io/hashicorp/bar"]
`

const testTransformPruneProviderBasicStr = `
foo_instance.web
  provider["registry.terraform.io/hashicorp/foo"]
provider["registry.terraform.io/hashicorp/foo"]
provider["registry.terraform.io/hashicorp/foo"] (close)
  foo_instance.web
  provider["registry.terraform.io/hashicorp/foo"]
`

const testTransformModuleProviderConfigStr = `
module.child.aws_instance.thing
  provider["registry.terraform.io/hashicorp/aws"].foo
provider["registry.terraform.io/hashicorp/aws"].foo
`

const testTransformModuleProviderGrandparentStr = `
module.child.module.grandchild.aws_instance.baz
  provider["registry.terraform.io/hashicorp/aws"].foo
provider["registry.terraform.io/hashicorp/aws"].foo
`
