package plans

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

// Changes describes various actions that Terraform will attempt to take if
// the corresponding plan is applied.
//
// A Changes object can be rendered into a visual diff (by the caller, using
// code in another package) for display to the user.
type Changes struct {
	// Resources tracks planned changes to resource instance objects.
	Resources []*ResourceInstanceChangeSrc

	// Outputs tracks planned changes output values.
	//
	// Note that although an in-memory plan contains planned changes for
	// outputs throughout the configuration, a plan serialized
	// to disk retains only the root outputs because they are
	// externally-visible, while other outputs are implementation details and
	// can be easily re-calculated during the apply phase. Therefore only root
	// module outputs will survive a round-trip through a plan file.
	Outputs []*OutputChangeSrc
}

// NewChanges returns a valid Changes object that describes no changes.
func NewChanges() *Changes {
	return &Changes{}
}

func (c *Changes) Empty() bool {
	for _, res := range c.Resources {
		if res.Action != NoOp || res.Moved() {
			return false
		}
	}

	for _, out := range c.Outputs {
		if out.Addr.Module.IsRoot() && out.Action != NoOp {
			return false
		}
	}

	return true
}

// ResourceInstance returns the planned change for the current object of the
// resource instance of the given address, if any. Returns nil if no change is
// planned.
func (c *Changes) ResourceInstance(addr addrs.AbsResourceInstance) *ResourceInstanceChangeSrc {
	for _, rc := range c.Resources {
		if rc.Addr.Equal(addr) && rc.DeposedKey == states.NotDeposed {
			return rc
		}
	}

	return nil

}

// InstancesForAbsResource returns the planned change for the current objects
// of the resource instances of the given address, if any. Returns nil if no
// changes are planned.
func (c *Changes) InstancesForAbsResource(addr addrs.AbsResource) []*ResourceInstanceChangeSrc {
	var changes []*ResourceInstanceChangeSrc
	for _, rc := range c.Resources {
		resAddr := rc.Addr.ContainingResource()
		if resAddr.Equal(addr) && rc.DeposedKey == states.NotDeposed {
			changes = append(changes, rc)
		}
	}

	return changes
}

// InstancesForConfigResource returns the planned change for the current objects
// of the resource instances of the given address, if any. Returns nil if no
// changes are planned.
func (c *Changes) InstancesForConfigResource(addr addrs.ConfigResource) []*ResourceInstanceChangeSrc {
	var changes []*ResourceInstanceChangeSrc
	for _, rc := range c.Resources {
		resAddr := rc.Addr.ContainingResource().Config()
		if resAddr.Equal(addr) && rc.DeposedKey == states.NotDeposed {
			changes = append(changes, rc)
		}
	}

	return changes
}

// ResourceInstanceDeposed returns the plan change of a deposed object of
// the resource instance of the given address, if any. Returns nil if no change
// is planned.
func (c *Changes) ResourceInstanceDeposed(addr addrs.AbsResourceInstance, key states.DeposedKey) *ResourceInstanceChangeSrc {
	for _, rc := range c.Resources {
		if rc.Addr.Equal(addr) && rc.DeposedKey == key {
			return rc
		}
	}

	return nil
}

// OutputValue returns the planned change for the output value with the
//  given address, if any. Returns nil if no change is planned.
func (c *Changes) OutputValue(addr addrs.AbsOutputValue) *OutputChangeSrc {
	for _, oc := range c.Outputs {
		if oc.Addr.Equal(addr) {
			return oc
		}
	}

	return nil
}

// OutputValues returns planned changes for all outputs for all module
// instances that reside in the parent path.  Returns nil if no changes are
// planned.
func (c *Changes) OutputValues(parent addrs.ModuleInstance, module addrs.ModuleCall) []*OutputChangeSrc {
	var res []*OutputChangeSrc

	for _, oc := range c.Outputs {
		// we can't evaluate root module outputs
		if oc.Addr.Module.Equal(addrs.RootModuleInstance) {
			continue
		}

		changeMod, changeCall := oc.Addr.Module.Call()
		// this does not reside on our parent instance path
		if !changeMod.Equal(parent) {
			continue
		}

		// this is not the module you're looking for
		if changeCall.Name != module.Name {
			continue
		}

		res = append(res, oc)

	}

	return res
}

// SyncWrapper returns a wrapper object around the receiver that can be used
// to make certain changes to the receiver in a concurrency-safe way, as long
// as all callers share the same wrapper object.
func (c *Changes) SyncWrapper() *ChangesSync {
	return &ChangesSync{
		changes: c,
	}
}

// ResourceInstanceChange describes a change to a particular resource instance
// object.
type ResourceInstanceChange struct {
	// Addr is the absolute address of the resource instance that the change
	// will apply to.
	Addr addrs.AbsResourceInstance

	// PrevRunAddr is the absolute address that this resource instance had at
	// the conclusion of a previous run.
	//
	// This will typically be the same as Addr, but can be different if the
	// previous resource instance was subject to a "moved" block that we
	// handled in the process of creating this plan.
	//
	// For the initial creation of a resource instance there isn't really any
	// meaningful "previous run address", but PrevRunAddr will still be set
	// equal to Addr in that case in order to simplify logic elsewhere which
	// aims to detect and react to the movement of instances between addresses.
	PrevRunAddr addrs.AbsResourceInstance

	// DeposedKey is the identifier for a deposed object associated with the
	// given instance, or states.NotDeposed if this change applies to the
	// current object.
	//
	// A Replace change for a resource with create_before_destroy set will
	// create a new DeposedKey temporarily during replacement. In that case,
	// DeposedKey in the plan is always states.NotDeposed, representing that
	// the current object is being replaced with the deposed.
	DeposedKey states.DeposedKey

	// Provider is the address of the provider configuration that was used
	// to plan this change, and thus the configuration that must also be
	// used to apply it.
	ProviderAddr addrs.AbsProviderConfig

	// Change is an embedded description of the change.
	Change

	// ActionReason is an optional extra indication of why we chose the
	// action recorded in Change.Action for this particular resource instance.
	//
	// This is an approximate mechanism only for the purpose of explaining the
	// plan to end-users in the UI and is not to be used for any
	// decision-making during the apply step; if apply behavior needs to vary
	// depending on the "action reason" then the information for that decision
	// must be recorded more precisely elsewhere for that purpose.
	//
	// Sometimes there might be more than one reason for choosing a particular
	// action. In that case, it's up to the codepath making that decision to
	// decide which value would provide the most relevant explanation to the
	// end-user and return that. It's not a goal of this field to represent
	// fine details about the planning process.
	ActionReason ResourceInstanceChangeActionReason

	// RequiredReplace is a set of paths that caused the change action to be
	// Replace rather than Update. Always nil if the change action is not
	// Replace.
	//
	// This is retained only for UI-plan-rendering purposes and so it does not
	// currently survive a round-trip through a saved plan file.
	RequiredReplace cty.PathSet

	// Private allows a provider to stash any extra data that is opaque to
	// Terraform that relates to this change. Terraform will save this
	// byte-for-byte and return it to the provider in the apply call.
	Private []byte
}

// Encode produces a variant of the reciever that has its change values
// serialized so it can be written to a plan file. Pass the implied type of the
// corresponding resource type schema for correct operation.
func (rc *ResourceInstanceChange) Encode(ty cty.Type) (*ResourceInstanceChangeSrc, error) {
	cs, err := rc.Change.Encode(ty)
	if err != nil {
		return nil, err
	}
	prevRunAddr := rc.PrevRunAddr
	if prevRunAddr.Resource.Resource.Type == "" {
		// Suggests an old caller that hasn't been properly updated to
		// populate this yet.
		prevRunAddr = rc.Addr
	}
	return &ResourceInstanceChangeSrc{
		Addr:            rc.Addr,
		PrevRunAddr:     prevRunAddr,
		DeposedKey:      rc.DeposedKey,
		ProviderAddr:    rc.ProviderAddr,
		ChangeSrc:       *cs,
		ActionReason:    rc.ActionReason,
		RequiredReplace: rc.RequiredReplace,
		Private:         rc.Private,
	}, err
}

func (rc *ResourceInstanceChange) Moved() bool {
	return !rc.Addr.Equal(rc.PrevRunAddr)
}

// Simplify will, where possible, produce a change with a simpler action than
// the receiever given a flag indicating whether the caller is dealing with
// a normal apply or a destroy. This flag deals with the fact that Terraform
// Core uses a specialized graph node type for destroying; only that
// specialized node should set "destroying" to true.
//
// The following table shows the simplification behavior:
//
//     Action    Destroying?   New Action
//     --------+-------------+-----------
//     Create    true          NoOp
//     Delete    false         NoOp
//     Replace   true          Delete
//     Replace   false         Create
//
// For any combination not in the above table, the Simplify just returns the
// receiver as-is.
func (rc *ResourceInstanceChange) Simplify(destroying bool) *ResourceInstanceChange {
	if destroying {
		switch rc.Action {
		case Delete:
			// We'll fall out and just return rc verbatim, then.
		case CreateThenDelete, DeleteThenCreate:
			return &ResourceInstanceChange{
				Addr:         rc.Addr,
				DeposedKey:   rc.DeposedKey,
				Private:      rc.Private,
				ProviderAddr: rc.ProviderAddr,
				Change: Change{
					Action: Delete,
					Before: rc.Before,
					After:  cty.NullVal(rc.Before.Type()),
				},
			}
		default:
			return &ResourceInstanceChange{
				Addr:         rc.Addr,
				DeposedKey:   rc.DeposedKey,
				Private:      rc.Private,
				ProviderAddr: rc.ProviderAddr,
				Change: Change{
					Action: NoOp,
					Before: rc.Before,
					After:  rc.Before,
				},
			}
		}
	} else {
		switch rc.Action {
		case Delete:
			return &ResourceInstanceChange{
				Addr:         rc.Addr,
				DeposedKey:   rc.DeposedKey,
				Private:      rc.Private,
				ProviderAddr: rc.ProviderAddr,
				Change: Change{
					Action: NoOp,
					Before: rc.Before,
					After:  rc.Before,
				},
			}
		case CreateThenDelete, DeleteThenCreate:
			return &ResourceInstanceChange{
				Addr:         rc.Addr,
				DeposedKey:   rc.DeposedKey,
				Private:      rc.Private,
				ProviderAddr: rc.ProviderAddr,
				Change: Change{
					Action: Create,
					Before: cty.NullVal(rc.After.Type()),
					After:  rc.After,
				},
			}
		}
	}

	// If we fall out here then our change is already simple enough.
	return rc
}

// ResourceInstanceChangeActionReason allows for some extra user-facing
// reasoning for why a particular change action was chosen for a particular
// resource instance.
//
// This only represents sufficient detail to give a suitable explanation to
// an end-user, and mustn't be used for any real decision-making during the
// apply step.
type ResourceInstanceChangeActionReason rune

//go:generate go run golang.org/x/tools/cmd/stringer -type=ResourceInstanceChangeActionReason changes.go

const (
	// In most cases there's no special reason for choosing a particular
	// action, which is represented by ResourceInstanceChangeNoReason.
	ResourceInstanceChangeNoReason ResourceInstanceChangeActionReason = 0

	// ResourceInstanceReplaceBecauseTainted indicates that the resource
	// instance must be replaced because its existing current object is
	// marked as "tainted".
	ResourceInstanceReplaceBecauseTainted ResourceInstanceChangeActionReason = 'T'

	// ResourceInstanceReplaceByRequest indicates that the resource instance
	// is planned to be replaced because a caller specifically asked for it
	// to be using ReplaceAddrs. (On the command line, the -replace=...
	// planning option.)
	ResourceInstanceReplaceByRequest ResourceInstanceChangeActionReason = 'R'

	// ResourceInstanceReplaceByTriggers indicates that the resource instance
	// is planned to be replaced because of a corresponding change in a
	// replace_triggered_by reference.
	ResourceInstanceReplaceByTriggers ResourceInstanceChangeActionReason = 'D'

	// ResourceInstanceReplaceBecauseCannotUpdate indicates that the resource
	// instance is planned to be replaced because the provider has indicated
	// that a requested change cannot be applied as an update.
	//
	// In this case, the RequiredReplace field will typically be populated on
	// the ResourceInstanceChange object to give information about specifically
	// which arguments changed in a non-updatable way.
	ResourceInstanceReplaceBecauseCannotUpdate ResourceInstanceChangeActionReason = 'F'

	// ResourceInstanceDeleteBecauseNoResourceConfig indicates that the
	// resource instance is planned to be deleted because there's no
	// corresponding resource configuration block in the configuration.
	ResourceInstanceDeleteBecauseNoResourceConfig ResourceInstanceChangeActionReason = 'N'

	// ResourceInstanceDeleteBecauseWrongRepetition indicates that the
	// resource instance is planned to be deleted because the instance key
	// type isn't consistent with the repetition mode selected in the
	// resource configuration.
	ResourceInstanceDeleteBecauseWrongRepetition ResourceInstanceChangeActionReason = 'W'

	// ResourceInstanceDeleteBecauseCountIndex indicates that the resource
	// instance is planned to be deleted because its integer instance key
	// is out of range for the current configured resource "count" value.
	ResourceInstanceDeleteBecauseCountIndex ResourceInstanceChangeActionReason = 'C'

	// ResourceInstanceDeleteBecauseEachKey indicates that the resource
	// instance is planned to be deleted because its string instance key
	// isn't one of the keys included in the current configured resource
	// "for_each" value.
	ResourceInstanceDeleteBecauseEachKey ResourceInstanceChangeActionReason = 'E'

	// ResourceInstanceDeleteBecauseNoModule indicates that the resource
	// instance is planned to be deleted because it belongs to a module
	// instance that's no longer declared in the configuration.
	//
	// This is less specific than the reasons we return for the various ways
	// a resource instance itself can be no longer declared, including both
	// the total removal of a module block and changes to its count/for_each
	// arguments. This difference in detail is out of pragmatism, because
	// potentially multiple nested modules could all contribute conflicting
	// specific reasons for a particular instance to no longer be declared.
	ResourceInstanceDeleteBecauseNoModule ResourceInstanceChangeActionReason = 'M'

	// ResourceInstanceReadBecauseConfigUnknown indicates that the resource
	// must be read during apply (rather than during planning) because its
	// configuration contains unknown values. This reason applies only to
	// data resources.
	ResourceInstanceReadBecauseConfigUnknown ResourceInstanceChangeActionReason = '?'

	// ResourceInstanceReadBecauseDependencyPending indicates that the resource
	// must be read during apply (rather than during planning) because it
	// depends on a managed resource instance which has its own changes
	// pending.
	ResourceInstanceReadBecauseDependencyPending ResourceInstanceChangeActionReason = '!'
)

// OutputChange describes a change to an output value.
type OutputChange struct {
	// Addr is the absolute address of the output value that the change
	// will apply to.
	Addr addrs.AbsOutputValue

	// Change is an embedded description of the change.
	//
	// For output value changes, the type constraint for the DynamicValue
	// instances is always cty.DynamicPseudoType.
	Change

	// Sensitive, if true, indicates that either the old or new value in the
	// change is sensitive and so a rendered version of the plan in the UI
	// should elide the actual values while still indicating the action of the
	// change.
	Sensitive bool
}

// Encode produces a variant of the reciever that has its change values
// serialized so it can be written to a plan file.
func (oc *OutputChange) Encode() (*OutputChangeSrc, error) {
	cs, err := oc.Change.Encode(cty.DynamicPseudoType)
	if err != nil {
		return nil, err
	}
	return &OutputChangeSrc{
		Addr:      oc.Addr,
		ChangeSrc: *cs,
		Sensitive: oc.Sensitive,
	}, err
}

// Change describes a single change with a given action.
type Change struct {
	// Action defines what kind of change is being made.
	Action Action

	// Interpretation of Before and After depend on Action:
	//
	//     NoOp     Before and After are the same, unchanged value
	//     Create   Before is nil, and After is the expected value after create.
	//     Read     Before is any prior value (nil if no prior), and After is the
	//              value that was or will be read.
	//     Update   Before is the value prior to update, and After is the expected
	//              value after update.
	//     Replace  As with Update.
	//     Delete   Before is the value prior to delete, and After is always nil.
	//
	// Unknown values may appear anywhere within the Before and After values,
	// either as the values themselves or as nested elements within known
	// collections/structures.
	Before, After cty.Value
}

// Encode produces a variant of the reciever that has its change values
// serialized so it can be written to a plan file. Pass the type constraint
// that the values are expected to conform to; to properly decode the values
// later an identical type constraint must be provided at that time.
//
// Where a Change is embedded in some other struct, it's generally better
// to call the corresponding Encode method of that struct rather than working
// directly with its embedded Change.
func (c *Change) Encode(ty cty.Type) (*ChangeSrc, error) {
	// Storing unmarked values so that we can encode unmarked values
	// and save the PathValueMarks for re-marking the values later
	var beforeVM, afterVM []cty.PathValueMarks
	unmarkedBefore := c.Before
	unmarkedAfter := c.After

	if c.Before.ContainsMarked() {
		unmarkedBefore, beforeVM = c.Before.UnmarkDeepWithPaths()
	}
	beforeDV, err := NewDynamicValue(unmarkedBefore, ty)
	if err != nil {
		return nil, err
	}

	if c.After.ContainsMarked() {
		unmarkedAfter, afterVM = c.After.UnmarkDeepWithPaths()
	}
	afterDV, err := NewDynamicValue(unmarkedAfter, ty)
	if err != nil {
		return nil, err
	}

	return &ChangeSrc{
		Action:         c.Action,
		Before:         beforeDV,
		After:          afterDV,
		BeforeValMarks: beforeVM,
		AfterValMarks:  afterVM,
	}, nil
}
