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

package addrs

import (
	"fmt"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

// MoveEndpoint is to AbsMoveable and ConfigMoveable what Target is to
// Targetable: a wrapping struct that captures the result of decoding an HCL
// traversal representing a relative path from the current module to
// a moveable object.
//
// Its name reflects that its primary purpose is for the "from" and "to"
// addresses in a "moved" statement in the configuration, but it's also
// valid to use MoveEndpoint for other similar mechanisms that give
// Terraform hints about historical configuration changes that might
// prompt creating a different plan than Terraform would by default.
//
// To obtain a full address from a MoveEndpoint you must use
// either the package function UnifyMoveEndpoints (to get an AbsMoveable) or
// the method ConfigMoveable (to get a ConfigMoveable).
type MoveEndpoint struct {
	// SourceRange is the location of the physical endpoint address
	// in configuration, if this MoveEndpoint was decoded from a
	// configuration expresson.
	SourceRange tfdiags.SourceRange

	// Internally we (ab)use AbsMoveable as the representation of our
	// relative address, even though everywhere else in Terraform
	// AbsMoveable always represents a fully-absolute address.
	// In practice, due to the implementation of ParseMoveEndpoint,
	// this is always either a ModuleInstance or an AbsResourceInstance,
	// and we only consider the possibility of interpreting it as
	// a AbsModuleCall or an AbsResource in UnifyMoveEndpoints.
	// This is intentionally unexported to encapsulate this unusual
	// meaning of AbsMoveable.
	relSubject AbsMoveable
}

func (e *MoveEndpoint) ObjectKind() MoveEndpointKind {
	return absMoveableEndpointKind(e.relSubject)
}

func (e *MoveEndpoint) String() string {
	// Our internal pseudo-AbsMoveable representing the relative
	// address (either ModuleInstance or AbsResourceInstance) is
	// a good enough proxy for the relative move endpoint address
	// serialization.
	return e.relSubject.String()
}

func (e *MoveEndpoint) Equal(other *MoveEndpoint) bool {
	switch {
	case (e == nil) != (other == nil):
		return false
	case e == nil:
		return true
	default:
		// Since we only use ModuleInstance and AbsResourceInstance in our
		// string representation, we have no ambiguity between address types
		// and can safely just compare the string representations to
		// compare the relSubject values.
		return e.String() == other.String() && e.SourceRange == other.SourceRange
	}
}

// MightUnifyWith returns true if it is possible that a later call to
// UnifyMoveEndpoints might succeed if given the reciever and the other
// given endpoint.
//
// This is intended for early static validation of obviously-wrong situations,
// although there are still various semantic errors that this cannot catch.
func (e *MoveEndpoint) MightUnifyWith(other *MoveEndpoint) bool {
	// For our purposes here we'll just do a unify without a base module
	// address, because the rules for whether unify can succeed depend
	// only on the relative part of the addresses, not on which module
	// they were declared in.
	from, to := UnifyMoveEndpoints(RootModule, e, other)
	return from != nil && to != nil
}

// ConfigMovable transforms the reciever into a ConfigMovable by resolving it
// relative to the given base module, which should be the module where
// the MoveEndpoint expression was found.
//
// The result is useful for finding the target object in the configuration,
// but it's not sufficient for fully interpreting a move statement because
// it lacks the specific module and resource instance keys.
func (e *MoveEndpoint) ConfigMoveable(baseModule Module) ConfigMoveable {
	addr := e.relSubject
	switch addr := addr.(type) {
	case ModuleInstance:
		ret := make(Module, 0, len(baseModule)+len(addr))
		ret = append(ret, baseModule...)
		ret = append(ret, addr.Module()...)
		return ret
	case AbsResourceInstance:
		moduleAddr := make(Module, 0, len(baseModule)+len(addr.Module))
		moduleAddr = append(moduleAddr, baseModule...)
		moduleAddr = append(moduleAddr, addr.Module.Module()...)
		return ConfigResource{
			Module:   moduleAddr,
			Resource: addr.Resource.Resource,
		}
	default:
		// The above should be exhaustive for all of the types
		// that ParseMoveEndpoint produces as our intermediate
		// address representation.
		panic(fmt.Sprintf("unsupported address type %T", addr))
	}

}

// ParseMoveEndpoint attempts to interpret the given traversal as a
// "move endpoint" address, which is a relative path from the module containing
// the traversal to a movable object in either the same module or in some
// child module.
//
// This deals only with the syntactic element of a move endpoint expression
// in configuration. Before the result will be useful you'll need to combine
// it with the address of the module where it was declared in order to get
// an absolute address relative to the root module.
func ParseMoveEndpoint(traversal hcl.Traversal) (*MoveEndpoint, tfdiags.Diagnostics) {
	path, remain, diags := parseModuleInstancePrefix(traversal)
	if diags.HasErrors() {
		return nil, diags
	}

	rng := tfdiags.SourceRangeFromHCL(traversal.SourceRange())

	if len(remain) == 0 {
		return &MoveEndpoint{
			relSubject:  path,
			SourceRange: rng,
		}, diags
	}

	riAddr, moreDiags := parseResourceInstanceUnderModule(path, remain)
	diags = diags.Append(moreDiags)
	if diags.HasErrors() {
		return nil, diags
	}

	return &MoveEndpoint{
		relSubject:  riAddr,
		SourceRange: rng,
	}, diags
}

// UnifyMoveEndpoints takes a pair of MoveEndpoint objects representing the
// "from" and "to" addresses in a moved block, and returns a pair of
// MoveEndpointInModule addresses guaranteed to be of the same dynamic type
// that represent what the two MoveEndpoint addresses refer to.
//
// moduleAddr must be the address of the module where the move was declared.
//
// This function deals both with the conversion from relative to absolute
// addresses and with resolving the ambiguity between no-key instance
// addresses and whole-object addresses, returning the least specific
// address type possible.
//
// Not all combinations of addresses are unifyable: the two addresses must
// either both include resources or both just be modules. If the two
// given addresses are incompatible then UnifyMoveEndpoints returns (nil, nil),
// in which case the caller should typically report an error to the user
// stating the unification constraints.
func UnifyMoveEndpoints(moduleAddr Module, relFrom, relTo *MoveEndpoint) (modFrom, modTo *MoveEndpointInModule) {

	// First we'll make a decision about which address type we're
	// ultimately trying to unify to. For our internal purposes
	// here we're going to borrow TargetableAddrType just as a
	// convenient way to talk about our address types, even though
	// targetable address types are not 100% aligned with moveable
	// address types.
	fromType := relFrom.internalAddrType()
	toType := relTo.internalAddrType()
	var wantType TargetableAddrType

	// Our goal here is to choose the whole-resource or whole-module-call
	// addresses if both agree on it, but to use specific instance addresses
	// otherwise. This is a somewhat-arbitrary way to resolve syntactic
	// ambiguity between the two situations which allows both for renaming
	// whole resources and for switching from a single-instance object to
	// a multi-instance object.
	switch {
	case fromType == AbsResourceInstanceAddrType || toType == AbsResourceInstanceAddrType:
		wantType = AbsResourceInstanceAddrType
	case fromType == AbsResourceAddrType || toType == AbsResourceAddrType:
		wantType = AbsResourceAddrType
	case fromType == ModuleInstanceAddrType || toType == ModuleInstanceAddrType:
		wantType = ModuleInstanceAddrType
	case fromType == ModuleAddrType || toType == ModuleAddrType:
		// NOTE: We're fudging a little here and using
		// ModuleAddrType to represent AbsModuleCall rather
		// than Module.
		wantType = ModuleAddrType
	default:
		panic("unhandled move address types")
	}

	modFrom = relFrom.prepareMoveEndpointInModule(moduleAddr, wantType)
	modTo = relTo.prepareMoveEndpointInModule(moduleAddr, wantType)
	if modFrom == nil || modTo == nil {
		// if either of them failed then they both failed, to make the
		// caller's life a little easier.
		return nil, nil
	}
	return modFrom, modTo
}

func (e *MoveEndpoint) prepareMoveEndpointInModule(moduleAddr Module, wantType TargetableAddrType) *MoveEndpointInModule {
	// relAddr can only be either AbsResourceInstance or ModuleInstance, the
	// internal intermediate representation produced by ParseMoveEndpoint.
	relAddr := e.relSubject

	switch relAddr := relAddr.(type) {
	case ModuleInstance:
		switch wantType {
		case ModuleInstanceAddrType:
			// Since our internal representation is already a module instance,
			// we can just rewrap this one.
			return &MoveEndpointInModule{
				SourceRange: e.SourceRange,
				module:      moduleAddr,
				relSubject:  relAddr,
			}
		case ModuleAddrType:
			// NOTE: We're fudging a little here and using
			// ModuleAddrType to represent AbsModuleCall rather
			// than Module.
			callerAddr, callAddr := relAddr.Call()
			absCallAddr := AbsModuleCall{
				Module: callerAddr,
				Call:   callAddr,
			}
			return &MoveEndpointInModule{
				SourceRange: e.SourceRange,
				module:      moduleAddr,
				relSubject:  absCallAddr,
			}
		default:
			return nil // can't make any other types from a ModuleInstance
		}
	case AbsResourceInstance:
		switch wantType {
		case AbsResourceInstanceAddrType:
			return &MoveEndpointInModule{
				SourceRange: e.SourceRange,
				module:      moduleAddr,
				relSubject:  relAddr,
			}
		case AbsResourceAddrType:
			return &MoveEndpointInModule{
				SourceRange: e.SourceRange,
				module:      moduleAddr,
				relSubject:  relAddr.ContainingResource(),
			}
		default:
			return nil // can't make any other types from an AbsResourceInstance
		}
	default:
		panic(fmt.Sprintf("unhandled address type %T", relAddr))
	}
}

// internalAddrType helps facilitate our slight abuse of TargetableAddrType
// as a way to talk about our different possible result address types in
// UnifyMoveEndpoints.
//
// It's not really correct to use TargetableAddrType in this way, because
// it's for Targetable rather than for AbsMoveable, but as long as the two
// remain aligned enough it saves introducing yet another enumeration with
// similar members that would be for internal use only anyway.
func (e *MoveEndpoint) internalAddrType() TargetableAddrType {
	switch addr := e.relSubject.(type) {
	case ModuleInstance:
		if !addr.IsRoot() && addr[len(addr)-1].InstanceKey == NoKey {
			// NOTE: We're fudging a little here and using
			// ModuleAddrType to represent AbsModuleCall rather
			// than Module.
			return ModuleAddrType
		}
		return ModuleInstanceAddrType
	case AbsResourceInstance:
		if addr.Resource.Key == NoKey {
			return AbsResourceAddrType
		}
		return AbsResourceInstanceAddrType
	default:
		// The above should cover all of the address types produced
		// by ParseMoveEndpoint.
		panic(fmt.Sprintf("unsupported address type %T", addr))
	}
}
