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

package terraform

import (
	"testing"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/hashicorp/terraform/internal/plans"
	"github.com/hashicorp/terraform/internal/providers"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/zclconf/go-cty/cty"
)

func TestNodePlanDeposedResourceInstanceObject_Execute(t *testing.T) {
	deposedKey := states.NewDeposedKey()
	state := states.NewState()
	absResource := mustResourceInstanceAddr("test_instance.foo")
	state.Module(addrs.RootModuleInstance).SetResourceInstanceDeposed(
		absResource.Resource,
		deposedKey,
		&states.ResourceInstanceObjectSrc{
			Status:    states.ObjectTainted,
			AttrsJSON: []byte(`{"id":"bar"}`),
		},
		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
	)

	p := testProvider("test")
	p.ConfigureProvider(providers.ConfigureProviderRequest{})
	p.UpgradeResourceStateResponse = &providers.UpgradeResourceStateResponse{
		UpgradedState: cty.ObjectVal(map[string]cty.Value{
			"id": cty.StringVal("bar"),
		}),
	}
	ctx := &MockEvalContext{
		StateState:        state.SyncWrapper(),
		PrevRunStateState: state.DeepCopy().SyncWrapper(),
		RefreshStateState: state.DeepCopy().SyncWrapper(),
		ProviderProvider:  p,
		ProviderSchemaSchema: &ProviderSchema{
			ResourceTypes: map[string]*configschema.Block{
				"test_instance": {
					Attributes: map[string]*configschema.Attribute{
						"id": {
							Type:     cty.String,
							Computed: true,
						},
					},
				},
			},
		},
		ChangesChanges: plans.NewChanges().SyncWrapper(),
	}

	node := NodePlanDeposedResourceInstanceObject{
		NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
			Addr: absResource,
			NodeAbstractResource: NodeAbstractResource{
				ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
			},
		},
		DeposedKey: deposedKey,
	}
	err := node.Execute(ctx, walkPlan)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}

	if !p.UpgradeResourceStateCalled {
		t.Errorf("UpgradeResourceState wasn't called; should've been called to upgrade the previous run's object")
	}
	if !p.ReadResourceCalled {
		t.Errorf("ReadResource wasn't called; should've been called to refresh the deposed object")
	}

	change := ctx.Changes().GetResourceInstanceChange(absResource, deposedKey)
	if got, want := change.ChangeSrc.Action, plans.Delete; got != want {
		t.Fatalf("wrong planned action\ngot:  %s\nwant: %s", got, want)
	}
}

func TestNodeDestroyDeposedResourceInstanceObject_Execute(t *testing.T) {
	deposedKey := states.NewDeposedKey()
	state := states.NewState()
	absResource := mustResourceInstanceAddr("test_instance.foo")
	state.Module(addrs.RootModuleInstance).SetResourceInstanceDeposed(
		absResource.Resource,
		deposedKey,
		&states.ResourceInstanceObjectSrc{
			Status:    states.ObjectTainted,
			AttrsJSON: []byte(`{"id":"bar"}`),
		},
		mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
	)

	schema := &ProviderSchema{
		ResourceTypes: map[string]*configschema.Block{
			"test_instance": {
				Attributes: map[string]*configschema.Attribute{
					"id": {
						Type:     cty.String,
						Computed: true,
					},
				},
			},
		},
	}

	p := testProvider("test")
	p.ConfigureProvider(providers.ConfigureProviderRequest{})
	p.GetProviderSchemaResponse = getProviderSchemaResponseFromProviderSchema(schema)

	p.UpgradeResourceStateResponse = &providers.UpgradeResourceStateResponse{
		UpgradedState: cty.ObjectVal(map[string]cty.Value{
			"id": cty.StringVal("bar"),
		}),
	}
	ctx := &MockEvalContext{
		StateState:           state.SyncWrapper(),
		ProviderProvider:     p,
		ProviderSchemaSchema: schema,
		ChangesChanges:       plans.NewChanges().SyncWrapper(),
	}

	node := NodeDestroyDeposedResourceInstanceObject{
		NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
			Addr: absResource,
			NodeAbstractResource: NodeAbstractResource{
				ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
			},
		},
		DeposedKey: deposedKey,
	}
	err := node.Execute(ctx, walkApply)

	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}

	if !state.Empty() {
		t.Fatalf("resources left in state after destroy")
	}
}

func TestNodeDestroyDeposedResourceInstanceObject_WriteResourceInstanceState(t *testing.T) {
	state := states.NewState()
	ctx := new(MockEvalContext)
	ctx.StateState = state.SyncWrapper()
	ctx.PathPath = addrs.RootModuleInstance
	mockProvider := mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{
		Attributes: map[string]*configschema.Attribute{
			"id": {
				Type:     cty.String,
				Optional: true,
			},
		},
	})
	ctx.ProviderProvider = mockProvider
	ctx.ProviderSchemaSchema = mockProvider.ProviderSchema()

	obj := &states.ResourceInstanceObject{
		Value: cty.ObjectVal(map[string]cty.Value{
			"id": cty.StringVal("i-abc123"),
		}),
		Status: states.ObjectReady,
	}
	node := &NodeDestroyDeposedResourceInstanceObject{
		NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
			NodeAbstractResource: NodeAbstractResource{
				ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/aws"]`),
			},
			Addr: mustResourceInstanceAddr("aws_instance.foo"),
		},
		DeposedKey: states.NewDeposedKey(),
	}
	err := node.writeResourceInstanceState(ctx, obj)
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}

	checkStateString(t, state, `
aws_instance.foo: (1 deposed)
  ID = <not created>
  provider = provider["registry.terraform.io/hashicorp/aws"]
  Deposed ID 1 = i-abc123
	`)
}

func TestNodeDestroyDeposedResourceInstanceObject_ExecuteMissingState(t *testing.T) {
	p := simpleMockProvider()
	ctx := &MockEvalContext{
		StateState:           states.NewState().SyncWrapper(),
		ProviderProvider:     simpleMockProvider(),
		ProviderSchemaSchema: p.ProviderSchema(),
		ChangesChanges:       plans.NewChanges().SyncWrapper(),
	}

	node := NodeDestroyDeposedResourceInstanceObject{
		NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
			Addr: mustResourceInstanceAddr("test_object.foo"),
			NodeAbstractResource: NodeAbstractResource{
				ResolvedProvider: mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
			},
		},
		DeposedKey: states.NewDeposedKey(),
	}
	err := node.Execute(ctx, walkApply)

	if err == nil {
		t.Fatal("expected error")
	}
}
