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

package instances

import (
	"fmt"
	"sort"

	"github.com/zclconf/go-cty/cty"

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

// expansion is an internal interface used to represent the different
// ways expansion can operate depending on how repetition is configured for
// an object.
type expansion interface {
	instanceKeys() []addrs.InstanceKey
	repetitionData(addrs.InstanceKey) RepetitionData
}

// expansionSingle is the expansion corresponding to no repetition arguments
// at all, producing a single object with no key.
//
// expansionSingleVal is the only valid value of this type.
type expansionSingle uintptr

var singleKeys = []addrs.InstanceKey{addrs.NoKey}
var expansionSingleVal expansionSingle

func (e expansionSingle) instanceKeys() []addrs.InstanceKey {
	return singleKeys
}

func (e expansionSingle) repetitionData(key addrs.InstanceKey) RepetitionData {
	if key != addrs.NoKey {
		panic("cannot use instance key with non-repeating object")
	}
	return RepetitionData{}
}

// expansionCount is the expansion corresponding to the "count" argument.
type expansionCount int

func (e expansionCount) instanceKeys() []addrs.InstanceKey {
	ret := make([]addrs.InstanceKey, int(e))
	for i := range ret {
		ret[i] = addrs.IntKey(i)
	}
	return ret
}

func (e expansionCount) repetitionData(key addrs.InstanceKey) RepetitionData {
	i := int(key.(addrs.IntKey))
	if i < 0 || i >= int(e) {
		panic(fmt.Sprintf("instance key %d out of range for count %d", i, e))
	}
	return RepetitionData{
		CountIndex: cty.NumberIntVal(int64(i)),
	}
}

// expansionForEach is the expansion corresponding to the "for_each" argument.
type expansionForEach map[string]cty.Value

func (e expansionForEach) instanceKeys() []addrs.InstanceKey {
	ret := make([]addrs.InstanceKey, 0, len(e))
	for k := range e {
		ret = append(ret, addrs.StringKey(k))
	}
	sort.Slice(ret, func(i, j int) bool {
		return ret[i].(addrs.StringKey) < ret[j].(addrs.StringKey)
	})
	return ret
}

func (e expansionForEach) repetitionData(key addrs.InstanceKey) RepetitionData {
	k := string(key.(addrs.StringKey))
	v, ok := e[k]
	if !ok {
		panic(fmt.Sprintf("instance key %q does not match any instance", k))
	}
	return RepetitionData{
		EachKey:   cty.StringVal(k),
		EachValue: v,
	}
}
