// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package refactoring

import (
	"sort"
	"testing"

	"github.com/google/go-cmp/cmp"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

func TestImpliedMoveStatements(t *testing.T) {
	resourceAddr := func(name string) addrs.AbsResource {
		return addrs.Resource{
			Mode: addrs.ManagedResourceMode,
			Type: "foo",
			Name: name,
		}.Absolute(addrs.RootModuleInstance)
	}

	nestedResourceAddr := func(mod, name string) addrs.AbsResource {
		return addrs.Resource{
			Mode: addrs.ManagedResourceMode,
			Type: "foo",
			Name: name,
		}.Absolute(addrs.RootModuleInstance.Child(mod, addrs.NoKey))
	}

	instObjState := func() *states.ResourceInstanceObjectSrc {
		return &states.ResourceInstanceObjectSrc{}
	}
	providerAddr := addrs.AbsProviderConfig{
		Module:   addrs.RootModule,
		Provider: addrs.MustParseProviderSourceString("hashicorp/foo"),
	}

	rootCfg, _ := loadRefactoringFixture(t, "testdata/move-statement-implied")
	prevRunState := states.BuildState(func(s *states.SyncState) {
		s.SetResourceInstanceCurrent(
			resourceAddr("formerly_count").Instance(addrs.IntKey(0)),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("formerly_count").Instance(addrs.IntKey(1)),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("now_count").Instance(addrs.NoKey),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("formerly_count_explicit").Instance(addrs.IntKey(0)),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("formerly_count_explicit").Instance(addrs.IntKey(1)),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("now_count_explicit").Instance(addrs.NoKey),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("now_for_each_formerly_count").Instance(addrs.IntKey(0)),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("now_for_each_formerly_no_count").Instance(addrs.NoKey),
			instObjState(),
			providerAddr,
		)

		// This "ambiguous" resource is representing a rare but possible
		// situation where we end up having a mixture of different index
		// types in the state at the same time. The main way to get into
		// this state would be to remove "count = 1" and then have the
		// provider fail to destroy the zero-key instance even though we
		// already created the no-key instance. Users can also get here
		// by using "terraform state mv" in weird ways.
		s.SetResourceInstanceCurrent(
			resourceAddr("ambiguous").Instance(addrs.NoKey),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			resourceAddr("ambiguous").Instance(addrs.IntKey(0)),
			instObjState(),
			providerAddr,
		)

		// Add two resource nested in a module to ensure we find these
		// recursively.
		s.SetResourceInstanceCurrent(
			nestedResourceAddr("child", "formerly_count").Instance(addrs.IntKey(0)),
			instObjState(),
			providerAddr,
		)
		s.SetResourceInstanceCurrent(
			nestedResourceAddr("child", "now_count").Instance(addrs.NoKey),
			instObjState(),
			providerAddr,
		)
	})

	explicitStmts := FindMoveStatements(rootCfg)
	got := ImpliedMoveStatements(rootCfg, prevRunState, explicitStmts)
	want := []MoveStatement{
		{
			From: addrs.ImpliedMoveStatementEndpoint(resourceAddr("formerly_count").Instance(addrs.IntKey(0)), tfdiags.SourceRange{}),
			To:   addrs.ImpliedMoveStatementEndpoint(resourceAddr("formerly_count").Instance(addrs.NoKey), tfdiags.SourceRange{}),
			Provider: &addrs.AbsProviderConfig{
				Provider: addrs.NewProvider("registry.terraform.io", "hashicorp", "foo"),
			},
			Implied: true,
			DeclRange: tfdiags.SourceRange{
				Filename: "testdata/move-statement-implied/move-statement-implied.tf",
				Start:    tfdiags.SourcePos{Line: 5, Column: 1, Byte: 180},
				End:      tfdiags.SourcePos{Line: 5, Column: 32, Byte: 211},
			},
		},

		// Found implied moves in a nested module, ignoring the explicit moves
		{
			From: addrs.ImpliedMoveStatementEndpoint(nestedResourceAddr("child", "formerly_count").Instance(addrs.IntKey(0)), tfdiags.SourceRange{}),
			To:   addrs.ImpliedMoveStatementEndpoint(nestedResourceAddr("child", "formerly_count").Instance(addrs.NoKey), tfdiags.SourceRange{}),
			Provider: &addrs.AbsProviderConfig{
				Module:   addrs.Module{"child"},
				Provider: addrs.NewProvider("registry.terraform.io", "hashicorp", "foo"),
			},
			Implied: true,
			DeclRange: tfdiags.SourceRange{
				Filename: "testdata/move-statement-implied/child/move-statement-implied.tf",
				Start:    tfdiags.SourcePos{Line: 5, Column: 1, Byte: 180},
				End:      tfdiags.SourcePos{Line: 5, Column: 32, Byte: 211},
			},
		},

		{
			From: addrs.ImpliedMoveStatementEndpoint(resourceAddr("now_count").Instance(addrs.NoKey), tfdiags.SourceRange{}),
			To:   addrs.ImpliedMoveStatementEndpoint(resourceAddr("now_count").Instance(addrs.IntKey(0)), tfdiags.SourceRange{}),
			Provider: &addrs.AbsProviderConfig{
				Provider: addrs.NewProvider("registry.terraform.io", "hashicorp", "foo"),
			},
			Implied: true,
			DeclRange: tfdiags.SourceRange{
				Filename: "testdata/move-statement-implied/move-statement-implied.tf",
				Start:    tfdiags.SourcePos{Line: 10, Column: 11, Byte: 282},
				End:      tfdiags.SourcePos{Line: 10, Column: 12, Byte: 283},
			},
		},

		// Found implied moves in a nested module, ignoring the explicit moves
		{
			From: addrs.ImpliedMoveStatementEndpoint(nestedResourceAddr("child", "now_count").Instance(addrs.NoKey), tfdiags.SourceRange{}),
			To:   addrs.ImpliedMoveStatementEndpoint(nestedResourceAddr("child", "now_count").Instance(addrs.IntKey(0)), tfdiags.SourceRange{}),
			Provider: &addrs.AbsProviderConfig{
				Module:   addrs.Module{"child"},
				Provider: addrs.NewProvider("registry.terraform.io", "hashicorp", "foo"),
			},
			Implied: true,
			DeclRange: tfdiags.SourceRange{
				Filename: "testdata/move-statement-implied/child/move-statement-implied.tf",
				Start:    tfdiags.SourcePos{Line: 10, Column: 11, Byte: 282},
				End:      tfdiags.SourcePos{Line: 10, Column: 12, Byte: 283},
			},
		},

		// We generate foo.ambiguous[0] to foo.ambiguous here, even though
		// there's already a foo.ambiguous in the state, because it's the
		// responsibility of the later ApplyMoves step to deal with the
		// situation where an object wants to move into an address already
		// occupied by another object.
		{
			From: addrs.ImpliedMoveStatementEndpoint(resourceAddr("ambiguous").Instance(addrs.IntKey(0)), tfdiags.SourceRange{}),
			To:   addrs.ImpliedMoveStatementEndpoint(resourceAddr("ambiguous").Instance(addrs.NoKey), tfdiags.SourceRange{}),
			Provider: &addrs.AbsProviderConfig{
				Provider: addrs.NewProvider("registry.terraform.io", "hashicorp", "foo"),
			},
			Implied: true,
			DeclRange: tfdiags.SourceRange{
				Filename: "testdata/move-statement-implied/move-statement-implied.tf",
				Start:    tfdiags.SourcePos{Line: 46, Column: 1, Byte: 806},
				End:      tfdiags.SourcePos{Line: 46, Column: 27, Byte: 832},
			},
		},
	}

	sort.Slice(got, func(i, j int) bool {
		// This is just an arbitrary sort to make the result consistent
		// regardless of what order the ImpliedMoveStatements function
		// visits the entries in the state/config.
		return got[i].DeclRange.Start.Line < got[j].DeclRange.Start.Line
	})

	if diff := cmp.Diff(want, got); diff != "" {
		t.Errorf("wrong result\n%s", diff)
	}
}
