// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

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