package terraform

import (
	"strings"

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

func evalReplaceTriggeredByExpr(expr hcl.Expression, keyData instances.RepetitionData) (*addrs.Reference, tfdiags.Diagnostics) {
	var ref *addrs.Reference
	var diags tfdiags.Diagnostics

	traversal, diags := triggersExprToTraversal(expr, keyData)
	if diags.HasErrors() {
		return nil, diags
	}

	// We now have a static traversal, so we can just turn it into an addrs.Reference.
	ref, ds := addrs.ParseRef(traversal)
	diags = diags.Append(ds)

	return ref, diags
}

// trggersExprToTraversal takes an hcl expression limited to the syntax allowed
// in replace_triggered_by, and converts it to a static traversal. The
// RepetitionData contains the data necessary to evaluate the only allowed
// variables in the expression, count.index and each.key.
func triggersExprToTraversal(expr hcl.Expression, keyData instances.RepetitionData) (hcl.Traversal, tfdiags.Diagnostics) {
	var trav hcl.Traversal
	var diags tfdiags.Diagnostics

	switch e := expr.(type) {
	case *hclsyntax.RelativeTraversalExpr:
		t, d := triggersExprToTraversal(e.Source, keyData)
		diags = diags.Append(d)
		trav = append(trav, t...)
		trav = append(trav, e.Traversal...)

	case *hclsyntax.ScopeTraversalExpr:
		// a static reference, we can just append the traversal
		trav = append(trav, e.Traversal...)

	case *hclsyntax.IndexExpr:
		// Get the collection from the index expression
		t, d := triggersExprToTraversal(e.Collection, keyData)
		diags = diags.Append(d)
		if diags.HasErrors() {
			return nil, diags
		}
		trav = append(trav, t...)

		// The index key is the only place where we could have variables that
		// reference count and each, so we need to parse those independently.
		idx, hclDiags := parseIndexKeyExpr(e.Key, keyData)
		diags = diags.Append(hclDiags)

		trav = append(trav, idx)

	default:
		// Something unexpected got through config validation. We're not sure
		// what it is, but we'll point it out in the diagnostics for the user
		// to fix.
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid replace_triggered_by expression",
			Detail:   "Unexpected expression found in replace_triggered_by.",
			Subject:  e.Range().Ptr(),
		})
	}

	return trav, diags
}

// parseIndexKeyExpr takes an hcl.Expression and parses it as an index key, while
// evaluating any references to count.index or each.key.
func parseIndexKeyExpr(expr hcl.Expression, keyData instances.RepetitionData) (hcl.TraverseIndex, hcl.Diagnostics) {
	idx := hcl.TraverseIndex{
		SrcRange: expr.Range(),
	}

	trav, diags := hcl.RelTraversalForExpr(expr)
	if diags.HasErrors() {
		return idx, diags
	}

	keyParts := []string{}

	for _, t := range trav {
		attr, ok := t.(hcl.TraverseAttr)
		if !ok {
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid index expression",
				Detail:   "Only constant values, count.index or each.key are allowed in index expressions.",
				Subject:  expr.Range().Ptr(),
			})
			return idx, diags
		}
		keyParts = append(keyParts, attr.Name)
	}

	switch strings.Join(keyParts, ".") {
	case "count.index":
		if keyData.CountIndex == cty.NilVal {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  `Reference to "count" in non-counted context`,
				Detail:   `The "count" object can only be used in "resource" blocks when the "count" argument is set.`,
				Subject:  expr.Range().Ptr(),
			})
		}
		idx.Key = keyData.CountIndex

	case "each.key":
		if keyData.EachKey == cty.NilVal {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  `Reference to "each" in context without for_each`,
				Detail:   `The "each" object can be used only in "resource" blocks when the "for_each" argument is set.`,
				Subject:  expr.Range().Ptr(),
			})
		}
		idx.Key = keyData.EachKey
	default:
		// Something may have slipped through validation, probably from a json
		// configuration.
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid index expression",
			Detail:   "Only constant values, count.index or each.key are allowed in index expressions.",
			Subject:  expr.Range().Ptr(),
		})
	}

	return idx, diags

}
