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

package globalref

import (
	"fmt"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/lang"
)

// ReferencesFromOutputValue returns all of the direct references from the
// value expression of the given output value. It doesn't include any indirect
// references.
func (a *Analyzer) ReferencesFromOutputValue(addr addrs.AbsOutputValue) []Reference {
	mc := a.ModuleConfig(addr.Module)
	if mc == nil {
		return nil
	}
	oc := mc.Outputs[addr.OutputValue.Name]
	if oc == nil {
		return nil
	}
	refs, _ := lang.ReferencesInExpr(oc.Expr)
	return absoluteRefs(addr.Module, refs)
}

// ReferencesFromResourceInstance returns all of the direct references from the
// definition of the resource instance at the given address. It doesn't include
// any indirect references.
//
// The result doesn't directly include references from a "count" or "for_each"
// expression belonging to the associated resource, but it will include any
// references to count.index, each.key, or each.value that appear in the
// expressions which you can then, if you wish, resolve indirectly using
// Analyzer.MetaReferences. Alternatively, you can use
// Analyzer.ReferencesFromResourceRepetition to get that same result directly.
func (a *Analyzer) ReferencesFromResourceInstance(addr addrs.AbsResourceInstance) []Reference {
	// Using MetaReferences for this is kinda overkill, since
	// lang.ReferencesInBlock would be sufficient really, but
	// this ensures we keep consistent in how we build the
	// resulting absolute references and otherwise aside from
	// some extra overhead this call boils down to a call to
	// lang.ReferencesInBlock anyway.
	fakeRef := Reference{
		ContainerAddr: addr.Module,
		LocalRef: &addrs.Reference{
			Subject: addr.Resource,
		},
	}
	return a.MetaReferences(fakeRef)
}

// ReferencesFromResourceRepetition returns the references from the given
// resource's for_each or count expression, or an empty set if the resource
// doesn't use repetition.
//
// This is a special-case sort of helper for use in situations where an
// expression might refer to count.index, each.key, or each.value, and thus
// we say that it depends indirectly on the repetition expression.
func (a *Analyzer) ReferencesFromResourceRepetition(addr addrs.AbsResource) []Reference {
	modCfg := a.ModuleConfig(addr.Module)
	if modCfg == nil {
		return nil
	}
	rc := modCfg.ResourceByAddr(addr.Resource)
	if rc == nil {
		return nil
	}

	// We're assuming here that resources can either have count or for_each,
	// but never both, because that's a requirement enforced by the language
	// decoder. But we'll assert it just to make sure we catch it if that
	// changes for some reason.
	if rc.ForEach != nil && rc.Count != nil {
		panic(fmt.Sprintf("%s has both for_each and count", addr))
	}

	switch {
	case rc.ForEach != nil:
		refs, _ := lang.ReferencesInExpr(rc.ForEach)
		return absoluteRefs(addr.Module, refs)
	case rc.Count != nil:
		refs, _ := lang.ReferencesInExpr(rc.Count)
		return absoluteRefs(addr.Module, refs)
	default:
		return nil
	}
}
