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

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{}),
			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{}),
			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{}),
			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{}),
			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{}),
			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)
	}
}
