package terraform

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"reflect"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"sync"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
	"github.com/zclconf/go-cty/cty"

	"github.com/mitchellh/copystructure"
)

// DiffChangeType is an enum with the kind of changes a diff has planned.
type DiffChangeType byte

const (
	DiffInvalid DiffChangeType = iota
	DiffNone
	DiffCreate
	DiffUpdate
	DiffDestroy
	DiffDestroyCreate

	// DiffRefresh is only used in the UI for displaying diffs.
	// Managed resource reads never appear in plan, and when data source
	// reads appear they are represented as DiffCreate in core before
	// transforming to DiffRefresh in the UI layer.
	DiffRefresh // TODO: Actually use DiffRefresh in core too, for less confusion
)

// multiVal matches the index key to a flatmapped set, list or map
var multiVal = regexp.MustCompile(`\.(#|%)$`)

// Diff tracks the changes that are necessary to apply a configuration
// to an existing infrastructure.
type Diff struct {
	// Modules contains all the modules that have a diff
	Modules []*ModuleDiff
}

// Prune cleans out unused structures in the diff without affecting
// the behavior of the diff at all.
//
// This is not safe to call concurrently. This is safe to call on a
// nil Diff.
func (d *Diff) Prune() {
	if d == nil {
		return
	}

	// Prune all empty modules
	newModules := make([]*ModuleDiff, 0, len(d.Modules))
	for _, m := range d.Modules {
		// If the module isn't empty, we keep it
		if !m.Empty() {
			newModules = append(newModules, m)
		}
	}
	if len(newModules) == 0 {
		newModules = nil
	}
	d.Modules = newModules
}

// AddModule adds the module with the given path to the diff.
//
// This should be the preferred method to add module diffs since it
// allows us to optimize lookups later as well as control sorting.
func (d *Diff) AddModule(path addrs.ModuleInstance) *ModuleDiff {
	// Lower the new-style address into a legacy-style address.
	// This requires that none of the steps have instance keys, which is
	// true for all addresses at the time of implementing this because
	// "count" and "for_each" are not yet implemented for modules.
	legacyPath := make([]string, len(path))
	for i, step := range path {
		if step.InstanceKey != addrs.NoKey {
			// FIXME: Once the rest of Terraform is ready to use count and
			// for_each, remove all of this and just write the addrs.ModuleInstance
			// value itself into the ModuleState.
			panic("diff cannot represent modules with count or for_each keys")
		}

		legacyPath[i] = step.Name
	}

	m := &ModuleDiff{Path: legacyPath}
	m.init()
	d.Modules = append(d.Modules, m)
	return m
}

// ModuleByPath is used to lookup the module diff for the given path.
// This should be the preferred lookup mechanism as it allows for future
// lookup optimizations.
func (d *Diff) ModuleByPath(path addrs.ModuleInstance) *ModuleDiff {
	if d == nil {
		return nil
	}
	for _, mod := range d.Modules {
		if mod.Path == nil {
			panic("missing module path")
		}
		modPath := normalizeModulePath(mod.Path)
		if modPath.String() == path.String() {
			return mod
		}
	}
	return nil
}

// RootModule returns the ModuleState for the root module
func (d *Diff) RootModule() *ModuleDiff {
	root := d.ModuleByPath(addrs.RootModuleInstance)
	if root == nil {
		panic("missing root module")
	}
	return root
}

// Empty returns true if the diff has no changes.
func (d *Diff) Empty() bool {
	if d == nil {
		return true
	}

	for _, m := range d.Modules {
		if !m.Empty() {
			return false
		}
	}

	return true
}

// Equal compares two diffs for exact equality.
//
// This is different from the Same comparison that is supported which
// checks for operation equality taking into account computed values. Equal
// instead checks for exact equality.
func (d *Diff) Equal(d2 *Diff) bool {
	// If one is nil, they must both be nil
	if d == nil || d2 == nil {
		return d == d2
	}

	// Sort the modules
	sort.Sort(moduleDiffSort(d.Modules))
	sort.Sort(moduleDiffSort(d2.Modules))

	// Copy since we have to modify the module destroy flag to false so
	// we don't compare that. TODO: delete this when we get rid of the
	// destroy flag on modules.
	dCopy := d.DeepCopy()
	d2Copy := d2.DeepCopy()
	for _, m := range dCopy.Modules {
		m.Destroy = false
	}
	for _, m := range d2Copy.Modules {
		m.Destroy = false
	}

	// Use DeepEqual
	return reflect.DeepEqual(dCopy, d2Copy)
}

// DeepCopy performs a deep copy of all parts of the Diff, making the
// resulting Diff safe to use without modifying this one.
func (d *Diff) DeepCopy() *Diff {
	copy, err := copystructure.Config{Lock: true}.Copy(d)
	if err != nil {
		panic(err)
	}

	return copy.(*Diff)
}

func (d *Diff) String() string {
	var buf bytes.Buffer

	keys := make([]string, 0, len(d.Modules))
	lookup := make(map[string]*ModuleDiff)
	for _, m := range d.Modules {
		addr := normalizeModulePath(m.Path)
		key := addr.String()
		keys = append(keys, key)
		lookup[key] = m
	}
	sort.Strings(keys)

	for _, key := range keys {
		m := lookup[key]
		mStr := m.String()

		// If we're the root module, we just write the output directly.
		if reflect.DeepEqual(m.Path, rootModulePath) {
			buf.WriteString(mStr + "\n")
			continue
		}

		buf.WriteString(fmt.Sprintf("%s:\n", key))

		s := bufio.NewScanner(strings.NewReader(mStr))
		for s.Scan() {
			buf.WriteString(fmt.Sprintf("  %s\n", s.Text()))
		}
	}

	return strings.TrimSpace(buf.String())
}

func (d *Diff) init() {
	if d.Modules == nil {
		rootDiff := &ModuleDiff{Path: rootModulePath}
		d.Modules = []*ModuleDiff{rootDiff}
	}
	for _, m := range d.Modules {
		m.init()
	}
}

// ModuleDiff tracks the differences between resources to apply within
// a single module.
type ModuleDiff struct {
	Path      []string
	Resources map[string]*InstanceDiff
	Destroy   bool // Set only by the destroy plan
}

func (d *ModuleDiff) init() {
	if d.Resources == nil {
		d.Resources = make(map[string]*InstanceDiff)
	}
	for _, r := range d.Resources {
		r.init()
	}
}

// ChangeType returns the type of changes that the diff for this
// module includes.
//
// At a module level, this will only be DiffNone, DiffUpdate, DiffDestroy, or
// DiffCreate. If an instance within the module has a DiffDestroyCreate
// then this will register as a DiffCreate for a module.
func (d *ModuleDiff) ChangeType() DiffChangeType {
	result := DiffNone
	for _, r := range d.Resources {
		change := r.ChangeType()
		switch change {
		case DiffCreate, DiffDestroy:
			if result == DiffNone {
				result = change
			}
		case DiffDestroyCreate, DiffUpdate:
			result = DiffUpdate
		}
	}

	return result
}

// Empty returns true if the diff has no changes within this module.
func (d *ModuleDiff) Empty() bool {
	if d.Destroy {
		return false
	}

	if len(d.Resources) == 0 {
		return true
	}

	for _, rd := range d.Resources {
		if !rd.Empty() {
			return false
		}
	}

	return true
}

// Instances returns the instance diffs for the id given. This can return
// multiple instance diffs if there are counts within the resource.
func (d *ModuleDiff) Instances(id string) []*InstanceDiff {
	var result []*InstanceDiff
	for k, diff := range d.Resources {
		if k == id || strings.HasPrefix(k, id+".") {
			if !diff.Empty() {
				result = append(result, diff)
			}
		}
	}

	return result
}

// IsRoot says whether or not this module diff is for the root module.
func (d *ModuleDiff) IsRoot() bool {
	return reflect.DeepEqual(d.Path, rootModulePath)
}

// String outputs the diff in a long but command-line friendly output
// format that users can read to quickly inspect a diff.
func (d *ModuleDiff) String() string {
	var buf bytes.Buffer

	names := make([]string, 0, len(d.Resources))
	for name, _ := range d.Resources {
		names = append(names, name)
	}
	sort.Strings(names)

	for _, name := range names {
		rdiff := d.Resources[name]

		crud := "UPDATE"
		switch {
		case rdiff.RequiresNew() && (rdiff.GetDestroy() || rdiff.GetDestroyTainted()):
			crud = "DESTROY/CREATE"
		case rdiff.GetDestroy() || rdiff.GetDestroyDeposed():
			crud = "DESTROY"
		case rdiff.RequiresNew():
			crud = "CREATE"
		}

		extra := ""
		if !rdiff.GetDestroy() && rdiff.GetDestroyDeposed() {
			extra = " (deposed only)"
		}

		buf.WriteString(fmt.Sprintf(
			"%s: %s%s\n",
			crud,
			name,
			extra))

		keyLen := 0
		rdiffAttrs := rdiff.CopyAttributes()
		keys := make([]string, 0, len(rdiffAttrs))
		for key, _ := range rdiffAttrs {
			if key == "id" {
				continue
			}

			keys = append(keys, key)
			if len(key) > keyLen {
				keyLen = len(key)
			}
		}
		sort.Strings(keys)

		for _, attrK := range keys {
			attrDiff, _ := rdiff.GetAttribute(attrK)

			v := attrDiff.New
			u := attrDiff.Old
			if attrDiff.NewComputed {
				v = "<computed>"
			}

			if attrDiff.Sensitive {
				u = "<sensitive>"
				v = "<sensitive>"
			}

			updateMsg := ""
			if attrDiff.RequiresNew {
				updateMsg = " (forces new resource)"
			} else if attrDiff.Sensitive {
				updateMsg = " (attribute changed)"
			}

			buf.WriteString(fmt.Sprintf(
				"  %s:%s %#v => %#v%s\n",
				attrK,
				strings.Repeat(" ", keyLen-len(attrK)),
				u,
				v,
				updateMsg))
		}
	}

	return buf.String()
}

// InstanceDiff is the diff of a resource from some state to another.
type InstanceDiff struct {
	mu             sync.Mutex
	Attributes     map[string]*ResourceAttrDiff
	Destroy        bool
	DestroyDeposed bool
	DestroyTainted bool

	// Meta is a simple K/V map that is stored in a diff and persisted to
	// plans but otherwise is completely ignored by Terraform core. It is
	// meant to be used for additional data a resource may want to pass through.
	// The value here must only contain Go primitives and collections.
	Meta map[string]interface{}
}

func (d *InstanceDiff) Lock()   { d.mu.Lock() }
func (d *InstanceDiff) Unlock() { d.mu.Unlock() }

// ApplyToValue merges the receiver into the given base value, returning a
// new value that incorporates the planned changes. The given value must
// conform to the given schema, or this method will panic.
//
// This method is intended for shimming old subsystems that still use this
// legacy diff type to work with the new-style types.
func (d *InstanceDiff) ApplyToValue(base cty.Value, schema *configschema.Block) (cty.Value, error) {
	// Create an InstanceState attributes from our existing state.
	// We can use this to more easily apply the diff changes.
	attrs := hcl2shim.FlatmapValueFromHCL2(base)
	applied, err := d.Apply(attrs, schema)
	if err != nil {
		return base, err
	}

	val, err := hcl2shim.HCL2ValueFromFlatmap(applied, schema.ImpliedType())
	if err != nil {
		return base, err
	}

	return schema.CoerceValue(val)
}

// Apply applies the diff to the provided flatmapped attributes,
// returning the new instance attributes.
//
// This method is intended for shimming old subsystems that still use this
// legacy diff type to work with the new-style types.
func (d *InstanceDiff) Apply(attrs map[string]string, schema *configschema.Block) (map[string]string, error) {
	// We always build a new value here, even if the given diff is "empty",
	// because we might be planning to create a new instance that happens
	// to have no attributes set, and so we want to produce an empty object
	// rather than just echoing back the null old value.
	if attrs == nil {
		attrs = map[string]string{}
	}

	// Rather applying the diff to mutate the attrs, we'll copy new values into
	// here to avoid the possibility of leaving stale values.
	result := map[string]string{}

	if d.Destroy || d.DestroyDeposed || d.DestroyTainted {
		return result, nil
	}

	return d.applyBlockDiff(nil, attrs, schema)
}

func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, schema *configschema.Block) (map[string]string, error) {
	result := map[string]string{}
	name := ""
	if len(path) > 0 {
		name = path[len(path)-1]
	}

	// localPrefix is used to build the local result map
	localPrefix := ""
	if name != "" {
		localPrefix = name + "."
	}

	// iterate over the schema rather than the attributes, so we can handle
	// different block types separately from plain attributes
	for n, attrSchema := range schema.Attributes {
		var err error
		newAttrs, err := d.applyAttrDiff(append(path, n), attrs, attrSchema)

		if err != nil {
			return result, err
		}

		for k, v := range newAttrs {
			result[localPrefix+k] = v
		}
	}

	blockPrefix := strings.Join(path, ".")
	if blockPrefix != "" {
		blockPrefix += "."
	}
	for n, block := range schema.BlockTypes {
		// we need to find the set of all keys that traverse this block
		candidateKeys := map[string]bool{}
		blockKey := blockPrefix + n + "."
		localBlockPrefix := localPrefix + n + "."

		// we can only trust the diff for sets, since the path changes, so don't
		// count existing values as candidate keys. If it turns out we're
		// keeping the attributes, we will catch it down below with "keepBlock"
		// after we check the set count.
		if block.Nesting != configschema.NestingSet {
			for k := range attrs {
				if strings.HasPrefix(k, blockKey) {
					nextDot := strings.Index(k[len(blockKey):], ".")
					if nextDot < 0 {
						continue
					}
					nextDot += len(blockKey)
					candidateKeys[k[len(blockKey):nextDot]] = true
				}
			}
		}

		for k, diff := range d.Attributes {
			// helper/schema should not insert nil diff values, but don't panic
			// if it does.
			if diff == nil {
				continue
			}

			if strings.HasPrefix(k, blockKey) {
				nextDot := strings.Index(k[len(blockKey):], ".")
				if nextDot < 0 {
					continue
				}

				if diff.NewRemoved {
					continue
				}

				nextDot += len(blockKey)
				candidateKeys[k[len(blockKey):nextDot]] = true
			}
		}

		// check each set candidate to see if it was removed.
		// we need to do this, because when entire sets are removed, they may
		// have the wrong key, and ony show diffs going to ""
		if block.Nesting == configschema.NestingSet {
			for k := range candidateKeys {
				indexPrefix := strings.Join(append(path, n, k), ".") + "."
				keep := false
				// now check each set element to see if it's a new diff, or one
				// that we're dropping. Since we're only applying the "New"
				// portion of the set, we can ignore diffs that only contain "Old"
				for attr, diff := range d.Attributes {
					// helper/schema should not insert nil diff values, but don't panic
					// if it does.
					if diff == nil {
						continue
					}

					if !strings.HasPrefix(attr, indexPrefix) {
						continue
					}

					// check for empty "count" keys
					if (strings.HasSuffix(attr, ".#") || strings.HasSuffix(attr, ".%")) && diff.New == "0" {
						continue
					}

					// removed items don't count either
					if diff.NewRemoved {
						continue
					}

					// this must be a diff to keep
					keep = true
					break
				}
				if !keep {
					delete(candidateKeys, k)
				}
			}
		}

		for k := range candidateKeys {
			newAttrs, err := d.applyBlockDiff(append(path, n, k), attrs, &block.Block)
			if err != nil {
				return result, err
			}

			for attr, v := range newAttrs {
				result[localBlockPrefix+attr] = v
			}
		}

		keepBlock := true
		// check this block's count diff directly first, since we may not
		// have candidates because it was removed and only set to "0"
		if diff, ok := d.Attributes[blockKey+"#"]; ok {
			if diff.New == "0" || diff.NewRemoved {
				keepBlock = false
			}
		}

		// if there was no diff at all, then we need to keep the block attributes
		if len(candidateKeys) == 0 && keepBlock {
			for k, v := range attrs {
				if strings.HasPrefix(k, blockKey) {
					// we need the key relative to this block, so remove the
					// entire prefix, then re-insert the block name.
					localKey := localBlockPrefix + k[len(blockKey):]
					result[localKey] = v
				}
			}
		}

		countAddr := strings.Join(append(path, n, "#"), ".")
		if countDiff, ok := d.Attributes[countAddr]; ok {
			if countDiff.NewComputed {
				result[localBlockPrefix+"#"] = hcl2shim.UnknownVariableValue
			} else {
				result[localBlockPrefix+"#"] = countDiff.New

				// While sets are complete, list are not, and we may not have all the
				// information to track removals. If the list was truncated, we need to
				// remove the extra items from the result.
				if block.Nesting == configschema.NestingList &&
					countDiff.New != "" && countDiff.New != hcl2shim.UnknownVariableValue {
					length, _ := strconv.Atoi(countDiff.New)
					for k := range result {
						if !strings.HasPrefix(k, localBlockPrefix) {
							continue
						}

						index := k[len(localBlockPrefix):]
						nextDot := strings.Index(index, ".")
						if nextDot < 1 {
							continue
						}
						index = index[:nextDot]
						i, err := strconv.Atoi(index)
						if err != nil {
							// this shouldn't happen since we added these
							// ourself, but make note of it just in case.
							log.Printf("[ERROR] bad list index in %q: %s", k, err)
							continue
						}
						if i >= length {
							delete(result, k)
						}
					}
				}
			}
		} else if origCount, ok := attrs[countAddr]; ok && keepBlock {
			result[localBlockPrefix+"#"] = origCount
		} else {
			result[localBlockPrefix+"#"] = countFlatmapContainerValues(localBlockPrefix+"#", result)
		}
	}

	return result, nil
}

func (d *InstanceDiff) applyAttrDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) {
	ty := attrSchema.Type
	switch {
	case ty.IsListType(), ty.IsTupleType(), ty.IsMapType():
		return d.applyCollectionDiff(path, attrs, attrSchema)
	case ty.IsSetType():
		return d.applySetDiff(path, attrs, attrSchema)
	default:
		return d.applySingleAttrDiff(path, attrs, attrSchema)
	}
}

func (d *InstanceDiff) applySingleAttrDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) {
	currentKey := strings.Join(path, ".")

	attr := path[len(path)-1]

	result := map[string]string{}
	diff := d.Attributes[currentKey]
	old, exists := attrs[currentKey]

	if diff != nil && diff.NewComputed {
		result[attr] = hcl2shim.UnknownVariableValue
		return result, nil
	}

	// "id" must exist and not be an empty string, or it must be unknown.
	// This only applied to top-level "id" fields.
	if attr == "id" && len(path) == 1 {
		if old == "" {
			result[attr] = hcl2shim.UnknownVariableValue
		} else {
			result[attr] = old
		}
		return result, nil
	}

	// attribute diffs are sometimes missed, so assume no diff means keep the
	// old value
	if diff == nil {
		if exists {
			result[attr] = old
		} else {
			// We need required values, so set those with an empty value. It
			// must be set in the config, since if it were missing it would have
			// failed validation.
			if attrSchema.Required {
				// we only set a missing string here, since bool or number types
				// would have distinct zero value which shouldn't have been
				// lost.
				if attrSchema.Type == cty.String {
					result[attr] = ""
				}
			}
		}
		return result, nil
	}

	// check for missmatched diff values
	if exists &&
		old != diff.Old &&
		old != hcl2shim.UnknownVariableValue &&
		diff.Old != hcl2shim.UnknownVariableValue {
		return result, fmt.Errorf("diff apply conflict for %s: diff expects %q, but prior value has %q", attr, diff.Old, old)
	}

	if diff.NewRemoved {
		// don't set anything in the new value
		return map[string]string{}, nil
	}

	if diff.Old == diff.New && diff.New == "" {
		// this can only be a valid empty string
		if attrSchema.Type == cty.String {
			result[attr] = ""
		}
		return result, nil
	}

	if attrSchema.Computed && diff.NewComputed {
		result[attr] = hcl2shim.UnknownVariableValue
		return result, nil
	}

	result[attr] = diff.New

	return result, nil
}

func (d *InstanceDiff) applyCollectionDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) {
	result := map[string]string{}

	prefix := ""
	if len(path) > 1 {
		prefix = strings.Join(path[:len(path)-1], ".") + "."
	}

	name := ""
	if len(path) > 0 {
		name = path[len(path)-1]
	}

	currentKey := prefix + name

	// check the index first for special handling
	for k, diff := range d.Attributes {
		// check the index value, which can be set, and 0
		if k == currentKey+".#" || k == currentKey+".%" || k == currentKey {
			if diff.NewRemoved {
				return result, nil
			}

			if diff.NewComputed {
				result[k[len(prefix):]] = hcl2shim.UnknownVariableValue
				return result, nil
			}

			// do what the diff tells us to here, so that it's consistent with applies
			if diff.New == "0" {
				result[k[len(prefix):]] = "0"
				return result, nil
			}
		}
	}

	// collect all the keys from the diff and the old state
	noDiff := true
	keys := map[string]bool{}
	for k := range d.Attributes {
		if !strings.HasPrefix(k, currentKey+".") {
			continue
		}
		noDiff = false
		keys[k] = true
	}

	noAttrs := true
	for k := range attrs {
		if !strings.HasPrefix(k, currentKey+".") {
			continue
		}
		noAttrs = false
		keys[k] = true
	}

	// If there's no diff and no attrs, then there's no value at all.
	// This prevents an unexpected zero-count attribute in the attributes.
	if noDiff && noAttrs {
		return result, nil
	}

	idx := "#"
	if attrSchema.Type.IsMapType() {
		idx = "%"
	}

	for k := range keys {
		// generate an schema placeholder for the values
		elSchema := &configschema.Attribute{
			Type: attrSchema.Type.ElementType(),
		}

		res, err := d.applySingleAttrDiff(append(path, k[len(currentKey)+1:]), attrs, elSchema)
		if err != nil {
			return result, err
		}

		for k, v := range res {
			result[name+"."+k] = v
		}
	}

	// Just like in nested list blocks, for simple lists we may need to fill in
	// missing empty strings.
	countKey := name + "." + idx
	count := result[countKey]
	length, _ := strconv.Atoi(count)

	if count != "" && count != hcl2shim.UnknownVariableValue &&
		attrSchema.Type.Equals(cty.List(cty.String)) {
		// insert empty strings into missing indexes
		for i := 0; i < length; i++ {
			key := fmt.Sprintf("%s.%d", name, i)
			if _, ok := result[key]; !ok {
				result[key] = ""
			}
		}
	}

	// now check for truncation in any type of list
	if attrSchema.Type.IsListType() {
		for key := range result {
			if key == countKey {
				continue
			}

			if len(key) <= len(name)+1 {
				// not sure what this is, but don't panic
				continue
			}

			index := key[len(name)+1:]

			// It is possible to have nested sets or maps, so look for another dot
			dot := strings.Index(index, ".")
			if dot > 0 {
				index = index[:dot]
			}

			// This shouldn't have any more dots, since the element type is only string.
			num, err := strconv.Atoi(index)
			if err != nil {
				log.Printf("[ERROR] bad list index in %q: %s", currentKey, err)
				continue
			}

			if num >= length {
				delete(result, key)
			}
		}
	}

	// Fill in the count value if it wasn't present in the diff for some reason,
	// or if there is no count at all.
	_, countDiff := d.Attributes[countKey]
	if result[countKey] == "" || (!countDiff && len(keys) != len(result)) {
		result[countKey] = countFlatmapContainerValues(countKey, result)
	}

	return result, nil
}

func (d *InstanceDiff) applySetDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) {
	// We only need this special behavior for sets of object.
	if !attrSchema.Type.ElementType().IsObjectType() {
		// The normal collection apply behavior will work okay for this one, then.
		return d.applyCollectionDiff(path, attrs, attrSchema)
	}

	// When we're dealing with a set of an object type we actually want to
	// use our normal _block type_ apply behaviors, so we'll construct ourselves
	// a synthetic schema that treats the object type as a block type and
	// then delegate to our block apply method.
	synthSchema := &configschema.Block{
		Attributes: make(map[string]*configschema.Attribute),
	}

	for name, ty := range attrSchema.Type.ElementType().AttributeTypes() {
		// We can safely make everything into an attribute here because in the
		// event that there are nested set attributes we'll end up back in
		// here again recursively and can then deal with the next level of
		// expansion.
		synthSchema.Attributes[name] = &configschema.Attribute{
			Type:     ty,
			Optional: true,
		}
	}

	parentPath := path[:len(path)-1]
	childName := path[len(path)-1]
	containerSchema := &configschema.Block{
		BlockTypes: map[string]*configschema.NestedBlock{
			childName: {
				Nesting: configschema.NestingSet,
				Block:   *synthSchema,
			},
		},
	}

	return d.applyBlockDiff(parentPath, attrs, containerSchema)
}

// countFlatmapContainerValues returns the number of values in the flatmapped container
// (set, map, list) indexed by key. The key argument is expected to include the
// trailing ".#", or ".%".
func countFlatmapContainerValues(key string, attrs map[string]string) string {
	if len(key) < 3 || !(strings.HasSuffix(key, ".#") || strings.HasSuffix(key, ".%")) {
		panic(fmt.Sprintf("invalid index value %q", key))
	}

	prefix := key[:len(key)-1]
	items := map[string]int{}

	for k := range attrs {
		if k == key {
			continue
		}
		if !strings.HasPrefix(k, prefix) {
			continue
		}

		suffix := k[len(prefix):]
		dot := strings.Index(suffix, ".")
		if dot > 0 {
			suffix = suffix[:dot]
		}

		items[suffix]++
	}
	return strconv.Itoa(len(items))
}

// ResourceAttrDiff is the diff of a single attribute of a resource.
type ResourceAttrDiff struct {
	Old         string      // Old Value
	New         string      // New Value
	NewComputed bool        // True if new value is computed (unknown currently)
	NewRemoved  bool        // True if this attribute is being removed
	NewExtra    interface{} // Extra information for the provider
	RequiresNew bool        // True if change requires new resource
	Sensitive   bool        // True if the data should not be displayed in UI output
	Type        DiffAttrType
}

// Empty returns true if the diff for this attr is neutral
func (d *ResourceAttrDiff) Empty() bool {
	return d.Old == d.New && !d.NewComputed && !d.NewRemoved
}

func (d *ResourceAttrDiff) GoString() string {
	return fmt.Sprintf("*%#v", *d)
}

// DiffAttrType is an enum type that says whether a resource attribute
// diff is an input attribute (comes from the configuration) or an
// output attribute (comes as a result of applying the configuration). An
// example input would be "ami" for AWS and an example output would be
// "private_ip".
type DiffAttrType byte

const (
	DiffAttrUnknown DiffAttrType = iota
	DiffAttrInput
	DiffAttrOutput
)

func (d *InstanceDiff) init() {
	if d.Attributes == nil {
		d.Attributes = make(map[string]*ResourceAttrDiff)
	}
}

func NewInstanceDiff() *InstanceDiff {
	return &InstanceDiff{Attributes: make(map[string]*ResourceAttrDiff)}
}

func (d *InstanceDiff) Copy() (*InstanceDiff, error) {
	if d == nil {
		return nil, nil
	}

	dCopy, err := copystructure.Config{Lock: true}.Copy(d)
	if err != nil {
		return nil, err
	}

	return dCopy.(*InstanceDiff), nil
}

// ChangeType returns the DiffChangeType represented by the diff
// for this single instance.
func (d *InstanceDiff) ChangeType() DiffChangeType {
	if d.Empty() {
		return DiffNone
	}

	if d.RequiresNew() && (d.GetDestroy() || d.GetDestroyTainted()) {
		return DiffDestroyCreate
	}

	if d.GetDestroy() || d.GetDestroyDeposed() {
		return DiffDestroy
	}

	if d.RequiresNew() {
		return DiffCreate
	}

	return DiffUpdate
}

// Empty returns true if this diff encapsulates no changes.
func (d *InstanceDiff) Empty() bool {
	if d == nil {
		return true
	}

	d.mu.Lock()
	defer d.mu.Unlock()
	return !d.Destroy &&
		!d.DestroyTainted &&
		!d.DestroyDeposed &&
		len(d.Attributes) == 0
}

// Equal compares two diffs for exact equality.
//
// This is different from the Same comparison that is supported which
// checks for operation equality taking into account computed values. Equal
// instead checks for exact equality.
func (d *InstanceDiff) Equal(d2 *InstanceDiff) bool {
	// If one is nil, they must both be nil
	if d == nil || d2 == nil {
		return d == d2
	}

	// Use DeepEqual
	return reflect.DeepEqual(d, d2)
}

// DeepCopy performs a deep copy of all parts of the InstanceDiff
func (d *InstanceDiff) DeepCopy() *InstanceDiff {
	copy, err := copystructure.Config{Lock: true}.Copy(d)
	if err != nil {
		panic(err)
	}

	return copy.(*InstanceDiff)
}

func (d *InstanceDiff) GoString() string {
	return fmt.Sprintf("*%#v", InstanceDiff{
		Attributes:     d.Attributes,
		Destroy:        d.Destroy,
		DestroyTainted: d.DestroyTainted,
		DestroyDeposed: d.DestroyDeposed,
	})
}

// RequiresNew returns true if the diff requires the creation of a new
// resource (implying the destruction of the old).
func (d *InstanceDiff) RequiresNew() bool {
	if d == nil {
		return false
	}

	d.mu.Lock()
	defer d.mu.Unlock()

	return d.requiresNew()
}

func (d *InstanceDiff) requiresNew() bool {
	if d == nil {
		return false
	}

	if d.DestroyTainted {
		return true
	}

	for _, rd := range d.Attributes {
		if rd != nil && rd.RequiresNew {
			return true
		}
	}

	return false
}

func (d *InstanceDiff) GetDestroyDeposed() bool {
	d.mu.Lock()
	defer d.mu.Unlock()

	return d.DestroyDeposed
}

func (d *InstanceDiff) SetDestroyDeposed(b bool) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.DestroyDeposed = b
}

// These methods are properly locked, for use outside other InstanceDiff
// methods but everywhere else within the terraform package.
// TODO refactor the locking scheme
func (d *InstanceDiff) SetTainted(b bool) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.DestroyTainted = b
}

func (d *InstanceDiff) GetDestroyTainted() bool {
	d.mu.Lock()
	defer d.mu.Unlock()

	return d.DestroyTainted
}

func (d *InstanceDiff) SetDestroy(b bool) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.Destroy = b
}

func (d *InstanceDiff) GetDestroy() bool {
	d.mu.Lock()
	defer d.mu.Unlock()

	return d.Destroy
}

func (d *InstanceDiff) SetAttribute(key string, attr *ResourceAttrDiff) {
	d.mu.Lock()
	defer d.mu.Unlock()

	d.Attributes[key] = attr
}

func (d *InstanceDiff) DelAttribute(key string) {
	d.mu.Lock()
	defer d.mu.Unlock()

	delete(d.Attributes, key)
}

func (d *InstanceDiff) GetAttribute(key string) (*ResourceAttrDiff, bool) {
	d.mu.Lock()
	defer d.mu.Unlock()

	attr, ok := d.Attributes[key]
	return attr, ok
}
func (d *InstanceDiff) GetAttributesLen() int {
	d.mu.Lock()
	defer d.mu.Unlock()

	return len(d.Attributes)
}

// Safely copies the Attributes map
func (d *InstanceDiff) CopyAttributes() map[string]*ResourceAttrDiff {
	d.mu.Lock()
	defer d.mu.Unlock()

	attrs := make(map[string]*ResourceAttrDiff)
	for k, v := range d.Attributes {
		attrs[k] = v
	}

	return attrs
}

// Same checks whether or not two InstanceDiff's are the "same". When
// we say "same", it is not necessarily exactly equal. Instead, it is
// just checking that the same attributes are changing, a destroy
// isn't suddenly happening, etc.
func (d *InstanceDiff) Same(d2 *InstanceDiff) (bool, string) {
	// we can safely compare the pointers without a lock
	switch {
	case d == nil && d2 == nil:
		return true, ""
	case d == nil || d2 == nil:
		return false, "one nil"
	case d == d2:
		return true, ""
	}

	d.mu.Lock()
	defer d.mu.Unlock()

	// If we're going from requiring new to NOT requiring new, then we have
	// to see if all required news were computed. If so, it is allowed since
	// computed may also mean "same value and therefore not new".
	oldNew := d.requiresNew()
	newNew := d2.RequiresNew()
	if oldNew && !newNew {
		oldNew = false

		// This section builds a list of ignorable attributes for requiresNew
		// by removing off any elements of collections going to zero elements.
		// For collections going to zero, they may not exist at all in the
		// new diff (and hence RequiresNew == false).
		ignoreAttrs := make(map[string]struct{})
		for k, diffOld := range d.Attributes {
			if !strings.HasSuffix(k, ".%") && !strings.HasSuffix(k, ".#") {
				continue
			}

			// This case is in here as a protection measure. The bug that this
			// code originally fixed (GH-11349) didn't have to deal with computed
			// so I'm not 100% sure what the correct behavior is. Best to leave
			// the old behavior.
			if diffOld.NewComputed {
				continue
			}

			// We're looking for the case a map goes to exactly 0.
			if diffOld.New != "0" {
				continue
			}

			// Found it! Ignore all of these. The prefix here is stripping
			// off the "%" so it is just "k."
			prefix := k[:len(k)-1]
			for k2, _ := range d.Attributes {
				if strings.HasPrefix(k2, prefix) {
					ignoreAttrs[k2] = struct{}{}
				}
			}
		}

		for k, rd := range d.Attributes {
			if _, ok := ignoreAttrs[k]; ok {
				continue
			}

			// If the field is requires new and NOT computed, then what
			// we have is a diff mismatch for sure. We set that the old
			// diff does REQUIRE a ForceNew.
			if rd != nil && rd.RequiresNew && !rd.NewComputed {
				oldNew = true
				break
			}
		}
	}

	if oldNew != newNew {
		return false, fmt.Sprintf(
			"diff RequiresNew; old: %t, new: %t", oldNew, newNew)
	}

	// Verify that destroy matches. The second boolean here allows us to
	// have mismatching Destroy if we're moving from RequiresNew true
	// to false above. Therefore, the second boolean will only pass if
	// we're moving from Destroy: true to false as well.
	if d.Destroy != d2.GetDestroy() && d.requiresNew() == oldNew {
		return false, fmt.Sprintf(
			"diff: Destroy; old: %t, new: %t", d.Destroy, d2.GetDestroy())
	}

	// Go through the old diff and make sure the new diff has all the
	// same attributes. To start, build up the check map to be all the keys.
	checkOld := make(map[string]struct{})
	checkNew := make(map[string]struct{})
	for k, _ := range d.Attributes {
		checkOld[k] = struct{}{}
	}
	for k, _ := range d2.CopyAttributes() {
		checkNew[k] = struct{}{}
	}

	// Make an ordered list so we are sure the approximated hashes are left
	// to process at the end of the loop
	keys := make([]string, 0, len(d.Attributes))
	for k, _ := range d.Attributes {
		keys = append(keys, k)
	}
	sort.StringSlice(keys).Sort()

	for _, k := range keys {
		diffOld := d.Attributes[k]

		if _, ok := checkOld[k]; !ok {
			// We're not checking this key for whatever reason (see where
			// check is modified).
			continue
		}

		// Remove this key since we'll never hit it again
		delete(checkOld, k)
		delete(checkNew, k)

		_, ok := d2.GetAttribute(k)
		if !ok {
			// If there's no new attribute, and the old diff expected the attribute
			// to be removed, that's just fine.
			if diffOld.NewRemoved {
				continue
			}

			// If the last diff was a computed value then the absense of
			// that value is allowed since it may mean the value ended up
			// being the same.
			if diffOld.NewComputed {
				ok = true
			}

			// No exact match, but maybe this is a set containing computed
			// values. So check if there is an approximate hash in the key
			// and if so, try to match the key.
			if strings.Contains(k, "~") {
				parts := strings.Split(k, ".")
				parts2 := append([]string(nil), parts...)

				re := regexp.MustCompile(`^~\d+$`)
				for i, part := range parts {
					if re.MatchString(part) {
						// we're going to consider this the base of a
						// computed hash, and remove all longer matching fields
						ok = true

						parts2[i] = `\d+`
						parts2 = parts2[:i+1]
						break
					}
				}

				re, err := regexp.Compile("^" + strings.Join(parts2, `\.`))
				if err != nil {
					return false, fmt.Sprintf("regexp failed to compile; err: %#v", err)
				}

				for k2, _ := range checkNew {
					if re.MatchString(k2) {
						delete(checkNew, k2)
					}
				}
			}

			// This is a little tricky, but when a diff contains a computed
			// list, set, or map that can only be interpolated after the apply
			// command has created the dependent resources, it could turn out
			// that the result is actually the same as the existing state which
			// would remove the key from the diff.
			if diffOld.NewComputed && (strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%")) {
				ok = true
			}

			// Similarly, in a RequiresNew scenario, a list that shows up in the plan
			// diff can disappear from the apply diff, which is calculated from an
			// empty state.
			if d.requiresNew() && (strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%")) {
				ok = true
			}

			if !ok {
				return false, fmt.Sprintf("attribute mismatch: %s", k)
			}
		}

		// search for the suffix of the base of a [computed] map, list or set.
		match := multiVal.FindStringSubmatch(k)

		if diffOld.NewComputed && len(match) == 2 {
			matchLen := len(match[1])

			// This is a computed list, set, or map, so remove any keys with
			// this prefix from the check list.
			kprefix := k[:len(k)-matchLen]
			for k2, _ := range checkOld {
				if strings.HasPrefix(k2, kprefix) {
					delete(checkOld, k2)
				}
			}
			for k2, _ := range checkNew {
				if strings.HasPrefix(k2, kprefix) {
					delete(checkNew, k2)
				}
			}
		}

		// We don't compare the values because we can't currently actually
		// guarantee to generate the same value two two diffs created from
		// the same state+config: we have some pesky interpolation functions
		// that do not behave as pure functions (uuid, timestamp) and so they
		// can be different each time a diff is produced.
		// FIXME: Re-organize our config handling so that we don't re-evaluate
		// expressions when we produce a second comparison diff during
		// apply (for EvalCompareDiff).
	}

	// Check for leftover attributes
	if len(checkNew) > 0 {
		extras := make([]string, 0, len(checkNew))
		for attr, _ := range checkNew {
			extras = append(extras, attr)
		}
		return false,
			fmt.Sprintf("extra attributes: %s", strings.Join(extras, ", "))
	}

	return true, ""
}

// moduleDiffSort implements sort.Interface to sort module diffs by path.
type moduleDiffSort []*ModuleDiff

func (s moduleDiffSort) Len() int      { return len(s) }
func (s moduleDiffSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s moduleDiffSort) Less(i, j int) bool {
	a := s[i]
	b := s[j]

	// If the lengths are different, then the shorter one always wins
	if len(a.Path) != len(b.Path) {
		return len(a.Path) < len(b.Path)
	}

	// Otherwise, compare lexically
	return strings.Join(a.Path, ".") < strings.Join(b.Path, ".")
}
