package globalref

import (
	"fmt"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/zclconf/go-cty/cty"
)

// Reference combines an addrs.Reference with the address of the module
// instance or resource instance where it was found.
//
// Because of the design of the Terraform language, our main model of
// references only captures the module-local part of the reference and assumes
// that it's always clear from context which module a reference belongs to.
// That's not true for globalref because our whole purpose is to work across
// module boundaries, and so this package in particular has its own
// representation of references.
type Reference struct {
	// ContainerAddr is always either addrs.ModuleInstance or
	// addrs.AbsResourceInstance. The latter is required if LocalRef's
	// subject is either an addrs.CountAddr or addrs.ForEachAddr, so
	// we can know which resource's repetition expression it's
	// referring to.
	ContainerAddr addrs.Targetable

	// LocalRef is a reference that would be resolved in the context
	// of the module instance or resource instance given in ContainerAddr.
	LocalRef *addrs.Reference
}

func absoluteRef(containerAddr addrs.Targetable, localRef *addrs.Reference) Reference {
	ret := Reference{
		ContainerAddr: containerAddr,
		LocalRef:      localRef,
	}
	// For simplicity's sake, we always reduce the ContainerAddr to be
	// just the module address unless it's a count.index, each.key, or
	// each.value reference, because for anything else it's immaterial
	// which resource it belongs to.
	switch localRef.Subject.(type) {
	case addrs.CountAttr, addrs.ForEachAttr:
		// nothing to do
	default:
		ret.ContainerAddr = ret.ModuleAddr()
	}
	return ret
}

func absoluteRefs(containerAddr addrs.Targetable, refs []*addrs.Reference) []Reference {
	if len(refs) == 0 {
		return nil
	}

	ret := make([]Reference, len(refs))
	for i, ref := range refs {
		ret[i] = absoluteRef(containerAddr, ref)
	}
	return ret
}

// ModuleAddr returns the address of the module where the reference would
// be resolved.
//
// This is either ContainerAddr directly if it's already just a module
// instance, or the module instance part of it if it's a resource instance.
func (r Reference) ModuleAddr() addrs.ModuleInstance {
	switch addr := r.ContainerAddr.(type) {
	case addrs.ModuleInstance:
		return addr
	case addrs.AbsResourceInstance:
		return addr.Module
	default:
		// NOTE: We're intentionally using only a subset of possible
		// addrs.Targetable implementations here, so anything else
		// is invalid.
		panic(fmt.Sprintf("reference has invalid container address type %T", addr))
	}
}

// ResourceInstance returns the address of the resource where the reference
// would be resolved, if there is one.
//
// Because not all references belong to resources, the extra boolean return
// value indicates whether the returned address is valid.
func (r Reference) ResourceInstance() (addrs.AbsResourceInstance, bool) {
	switch container := r.ContainerAddr.(type) {
	case addrs.ModuleInstance:
		moduleInstance := container

		switch ref := r.LocalRef.Subject.(type) {
		case addrs.Resource:
			return ref.Instance(addrs.NoKey).Absolute(moduleInstance), true
		case addrs.ResourceInstance:
			return ref.Absolute(moduleInstance), true
		}

		return addrs.AbsResourceInstance{}, false

	case addrs.AbsResourceInstance:
		return container, true
	default:
		// NOTE: We're intentionally using only a subset of possible
		// addrs.Targetable implementations here, so anything else
		// is invalid.
		panic(fmt.Sprintf("reference has invalid container address type %T", container))
	}
}

// DebugString returns an internal (but still somewhat Terraform-language-like)
// compact string representation of the reciever, which isn't an address that
// any of our usual address parsers could accept but still captures the
// essence of what the reference represents.
//
// The DebugString result is not suitable for end-user-oriented messages.
//
// DebugString is also not suitable for use as a unique key for a reference,
// because it's ambiguous (between a no-key resource instance and a resource)
// and because it discards the source location information in the LocalRef.
func (r Reference) DebugString() string {
	// As the doc comment insinuates, we don't have any real syntax for
	// "absolute references": references are always local, and targets are
	// always absolute but only include modules and resources.
	return r.ContainerAddr.String() + "::" + r.LocalRef.DisplayString()
}

// ResourceAttr converts the Reference value to a more specific ResourceAttr
// value.
//
// Because not all references belong to resources, the extra boolean return
// value indicates whether the returned address is valid.
func (r Reference) ResourceAttr() (ResourceAttr, bool) {
	res, ok := r.ResourceInstance()
	if !ok {
		return ResourceAttr{}, ok
	}

	traversal := r.LocalRef.Remaining

	path := make(cty.Path, len(traversal))
	for si, step := range traversal {
		switch ts := step.(type) {
		case hcl.TraverseRoot:
			path[si] = cty.GetAttrStep{
				Name: ts.Name,
			}
		case hcl.TraverseAttr:
			path[si] = cty.GetAttrStep{
				Name: ts.Name,
			}
		case hcl.TraverseIndex:
			path[si] = cty.IndexStep{
				Key: ts.Key,
			}
		default:
			panic(fmt.Sprintf("unsupported traversal step %#v", step))
		}
	}

	return ResourceAttr{
		Resource: res,
		Attr:     path,
	}, true
}

// addrKey returns the referenceAddrKey value for the item that
// this reference refers to, discarding any source location information.
//
// See the referenceAddrKey doc comment for more information on what this
// is suitable for.
func (r Reference) addrKey() referenceAddrKey {
	// This is a pretty arbitrary bunch of stuff. We include the type here
	// just to differentiate between no-key resource instances and resources.
	return referenceAddrKey(fmt.Sprintf("%s(%T)%s", r.ContainerAddr.String(), r.LocalRef.Subject, r.LocalRef.DisplayString()))
}

// referenceAddrKey is a special string type which conventionally contains
// a unique string representation of the object that a reference refers to,
// although not of the reference itself because it ignores the information
// that would differentiate two different references to the same object.
//
// The actual content of a referenceAddrKey is arbitrary, for internal use
// only. and subject to change in future. We use a named type here only to
// make it easier to see when we're intentionally using strings to uniquely
// identify absolute reference addresses.
type referenceAddrKey string

// ResourceAttr represents a global resource and attribute reference.
// This is a more specific form of the Reference type since it can only refer
// to a specific AbsResource and one of its attributes.
type ResourceAttr struct {
	Resource addrs.AbsResourceInstance
	Attr     cty.Path
}

func (r ResourceAttr) DebugString() string {
	return r.Resource.String() + tfdiags.FormatCtyPath(r.Attr)
}
