package format

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/hashicorp/hcl/v2/hclsyntax"
	"github.com/mitchellh/colorstring"
	"github.com/zclconf/go-cty/cty"
	ctyjson "github.com/zclconf/go-cty/cty/json"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/hashicorp/terraform/internal/lang/marks"
	"github.com/hashicorp/terraform/internal/plans"
	"github.com/hashicorp/terraform/internal/plans/objchange"
	"github.com/hashicorp/terraform/internal/states"
)

// DiffLanguage controls the description of the resource change reasons.
type DiffLanguage rune

//go:generate go run golang.org/x/tools/cmd/stringer -type=DiffLanguage diff.go

const (
	// DiffLanguageProposedChange indicates that the change is one which is
	// planned to be applied.
	DiffLanguageProposedChange DiffLanguage = 'P'

	// DiffLanguageDetectedDrift indicates that the change is detected drift
	// from the configuration.
	DiffLanguageDetectedDrift DiffLanguage = 'D'
)

// ResourceChange returns a string representation of a change to a particular
// resource, for inclusion in user-facing plan output.
//
// The resource schema must be provided along with the change so that the
// formatted change can reflect the configuration structure for the associated
// resource.
//
// If "color" is non-nil, it will be used to color the result. Otherwise,
// no color codes will be included.
func ResourceChange(
	change *plans.ResourceInstanceChange,
	schema *configschema.Block,
	color *colorstring.Colorize,
	language DiffLanguage,
) string {
	addr := change.Addr
	var buf bytes.Buffer

	if color == nil {
		color = &colorstring.Colorize{
			Colors:  colorstring.DefaultColors,
			Disable: true,
			Reset:   false,
		}
	}

	dispAddr := addr.String()
	if change.DeposedKey != states.NotDeposed {
		dispAddr = fmt.Sprintf("%s (deposed object %s)", dispAddr, change.DeposedKey)
	}

	switch change.Action {
	case plans.Create:
		buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] will be created"), dispAddr))
	case plans.Read:
		buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] will be read during apply"), dispAddr))
		switch change.ActionReason {
		case plans.ResourceInstanceReadBecauseConfigUnknown:
			buf.WriteString("\n  # (config refers to values not yet known)")
		case plans.ResourceInstanceReadBecauseDependencyPending:
			buf.WriteString("\n  # (depends on a resource or a module with changes pending)")
		}
	case plans.Update:
		switch language {
		case DiffLanguageProposedChange:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] will be updated in-place"), dispAddr))
		case DiffLanguageDetectedDrift:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] has changed"), dispAddr))
		default:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] update (unknown reason %s)"), dispAddr, language))
		}
	case plans.CreateThenDelete, plans.DeleteThenCreate:
		switch change.ActionReason {
		case plans.ResourceInstanceReplaceBecauseTainted:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] is tainted, so must be [bold][red]replaced"), dispAddr))
		case plans.ResourceInstanceReplaceByRequest:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] will be [bold][red]replaced[reset], as requested"), dispAddr))
		case plans.ResourceInstanceReplaceByTriggers:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] will be [bold][red]replaced[reset] due to changes in replace_triggered_by"), dispAddr))
		default:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] must be [bold][red]replaced"), dispAddr))
		}
	case plans.Delete:
		switch language {
		case DiffLanguageProposedChange:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] will be [bold][red]destroyed"), dispAddr))
		case DiffLanguageDetectedDrift:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] has been deleted"), dispAddr))
		default:
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] delete (unknown reason %s)"), dispAddr, language))
		}
		// We can sometimes give some additional detail about why we're
		// proposing to delete. We show this as additional notes, rather than
		// as additional wording in the main action statement, in an attempt
		// to make the "will be destroyed" message prominent and consistent
		// in all cases, for easier scanning of this often-risky action.
		switch change.ActionReason {
		case plans.ResourceInstanceDeleteBecauseNoResourceConfig:
			buf.WriteString(fmt.Sprintf("\n  # (because %s is not in configuration)", addr.Resource.Resource))
		case plans.ResourceInstanceDeleteBecauseNoMoveTarget:
			buf.WriteString(fmt.Sprintf("\n  # (because %s was moved to %s, which is not in configuration)", change.PrevRunAddr, addr.Resource.Resource))
		case plans.ResourceInstanceDeleteBecauseNoModule:
			// FIXME: Ideally we'd truncate addr.Module to reflect the earliest
			// step that doesn't exist, so it's clearer which call this refers
			// to, but we don't have enough information out here in the UI layer
			// to decide that; only the "expander" in Terraform Core knows
			// which module instance keys are actually declared.
			buf.WriteString(fmt.Sprintf("\n  # (because %s is not in configuration)", addr.Module))
		case plans.ResourceInstanceDeleteBecauseWrongRepetition:
			// We have some different variations of this one
			switch addr.Resource.Key.(type) {
			case nil:
				buf.WriteString("\n  # (because resource uses count or for_each)")
			case addrs.IntKey:
				buf.WriteString("\n  # (because resource does not use count)")
			case addrs.StringKey:
				buf.WriteString("\n  # (because resource does not use for_each)")
			}
		case plans.ResourceInstanceDeleteBecauseCountIndex:
			buf.WriteString(fmt.Sprintf("\n  # (because index %s is out of range for count)", addr.Resource.Key))
		case plans.ResourceInstanceDeleteBecauseEachKey:
			buf.WriteString(fmt.Sprintf("\n  # (because key %s is not in for_each map)", addr.Resource.Key))
		}
		if change.DeposedKey != states.NotDeposed {
			// Some extra context about this unusual situation.
			buf.WriteString(color.Color("\n  # (left over from a partially-failed replacement of this instance)"))
		}
	case plans.NoOp:
		if change.Moved() {
			buf.WriteString(fmt.Sprintf(color.Color("[bold]  # %s[reset] has moved to [bold]%s[reset]"), change.PrevRunAddr.String(), dispAddr))
			break
		}
		fallthrough
	default:
		// should never happen, since the above is exhaustive
		buf.WriteString(fmt.Sprintf("%s has an action the plan renderer doesn't support (this is a bug)", dispAddr))
	}
	buf.WriteString(color.Color("[reset]\n"))

	if change.Moved() && change.Action != plans.NoOp {
		buf.WriteString(fmt.Sprintf(color.Color("  # [reset](moved from %s)\n"), change.PrevRunAddr.String()))
	}

	if change.Moved() && change.Action == plans.NoOp {
		buf.WriteString("    ")
	} else {
		buf.WriteString(color.Color(DiffActionSymbol(change.Action)) + " ")
	}

	switch addr.Resource.Resource.Mode {
	case addrs.ManagedResourceMode:
		buf.WriteString(fmt.Sprintf(
			"resource %q %q",
			addr.Resource.Resource.Type,
			addr.Resource.Resource.Name,
		))
	case addrs.DataResourceMode:
		buf.WriteString(fmt.Sprintf(
			"data %q %q",
			addr.Resource.Resource.Type,
			addr.Resource.Resource.Name,
		))
	default:
		// should never happen, since the above is exhaustive
		buf.WriteString(addr.String())
	}

	buf.WriteString(" {")

	p := blockBodyDiffPrinter{
		buf:             &buf,
		color:           color,
		action:          change.Action,
		requiredReplace: change.RequiredReplace,
	}

	// Most commonly-used resources have nested blocks that result in us
	// going at least three traversals deep while we recurse here, so we'll
	// start with that much capacity and then grow as needed for deeper
	// structures.
	path := make(cty.Path, 0, 3)

	result := p.writeBlockBodyDiff(schema, change.Before, change.After, 6, path)
	if result.bodyWritten {
		buf.WriteString("\n")
		buf.WriteString(strings.Repeat(" ", 4))
	}
	buf.WriteString("}\n")

	return buf.String()
}

// OutputChanges returns a string representation of a set of changes to output
// values for inclusion in user-facing plan output.
//
// If "color" is non-nil, it will be used to color the result. Otherwise,
// no color codes will be included.
func OutputChanges(
	changes []*plans.OutputChangeSrc,
	color *colorstring.Colorize,
) string {
	var buf bytes.Buffer
	p := blockBodyDiffPrinter{
		buf:    &buf,
		color:  color,
		action: plans.Update, // not actually used in this case, because we're not printing a containing block
	}

	// We're going to reuse the codepath we used for printing resource block
	// diffs, by pretending that the set of defined outputs are the attributes
	// of some resource. It's a little forced to do this, but it gives us all
	// the same formatting heuristics as we normally use for resource
	// attributes.
	oldVals := make(map[string]cty.Value, len(changes))
	newVals := make(map[string]cty.Value, len(changes))
	synthSchema := &configschema.Block{
		Attributes: make(map[string]*configschema.Attribute, len(changes)),
	}
	for _, changeSrc := range changes {
		name := changeSrc.Addr.OutputValue.Name
		change, err := changeSrc.Decode()
		if err != nil {
			// It'd be weird to get a decoding error here because that would
			// suggest that Terraform itself just produced an invalid plan, and
			// we don't have any good way to ignore it in this codepath, so
			// we'll just log it and ignore it.
			log.Printf("[ERROR] format.OutputChanges: Failed to decode planned change for output %q: %s", name, err)
			continue
		}
		synthSchema.Attributes[name] = &configschema.Attribute{
			Type:      cty.DynamicPseudoType, // output types are decided dynamically based on the given value
			Optional:  true,
			Sensitive: change.Sensitive,
		}
		oldVals[name] = change.Before
		newVals[name] = change.After
	}

	p.writeBlockBodyDiff(synthSchema, cty.ObjectVal(oldVals), cty.ObjectVal(newVals), 2, nil)

	return buf.String()
}

type blockBodyDiffPrinter struct {
	buf             *bytes.Buffer
	color           *colorstring.Colorize
	action          plans.Action
	requiredReplace cty.PathSet
	// verbose is set to true when using the "diff" printer to format state
	verbose bool
}

type blockBodyDiffResult struct {
	bodyWritten       bool
	skippedAttributes int
	skippedBlocks     int
}

const (
	forcesNewResourceCaption = " [red]# forces replacement[reset]"
	sensitiveCaption         = "(sensitive value)"
)

// writeBlockBodyDiff writes attribute or block differences
// and returns true if any differences were found and written
func (p *blockBodyDiffPrinter) writeBlockBodyDiff(schema *configschema.Block, old, new cty.Value, indent int, path cty.Path) blockBodyDiffResult {
	path = ctyEnsurePathCapacity(path, 1)
	result := blockBodyDiffResult{}

	// write the attributes diff
	blankBeforeBlocks := p.writeAttrsDiff(schema.Attributes, old, new, indent, path, &result)
	p.writeSkippedAttr(result.skippedAttributes, indent+2)

	{
		blockTypeNames := make([]string, 0, len(schema.BlockTypes))
		for name := range schema.BlockTypes {
			blockTypeNames = append(blockTypeNames, name)
		}
		sort.Strings(blockTypeNames)

		for _, name := range blockTypeNames {
			blockS := schema.BlockTypes[name]
			oldVal := ctyGetAttrMaybeNull(old, name)
			newVal := ctyGetAttrMaybeNull(new, name)

			result.bodyWritten = true
			skippedBlocks := p.writeNestedBlockDiffs(name, blockS, oldVal, newVal, blankBeforeBlocks, indent, path)
			if skippedBlocks > 0 {
				result.skippedBlocks += skippedBlocks
			}

			// Always include a blank for any subsequent block types.
			blankBeforeBlocks = true
		}
		if result.skippedBlocks > 0 {
			noun := "blocks"
			if result.skippedBlocks == 1 {
				noun = "block"
			}
			p.buf.WriteString("\n\n")
			p.buf.WriteString(strings.Repeat(" ", indent+2))
			p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), result.skippedBlocks, noun))
		}
	}

	return result
}

func (p *blockBodyDiffPrinter) writeAttrsDiff(
	attrsS map[string]*configschema.Attribute,
	old, new cty.Value,
	indent int,
	path cty.Path,
	result *blockBodyDiffResult) bool {

	attrNames := make([]string, 0, len(attrsS))
	displayAttrNames := make(map[string]string, len(attrsS))
	attrNameLen := 0
	for name := range attrsS {
		oldVal := ctyGetAttrMaybeNull(old, name)
		newVal := ctyGetAttrMaybeNull(new, name)
		if oldVal.IsNull() && newVal.IsNull() {
			// Skip attributes where both old and new values are null
			// (we do this early here so that we'll do our value alignment
			// based on the longest attribute name that has a change, rather
			// than the longest attribute name in the full set.)
			continue
		}

		attrNames = append(attrNames, name)
		displayAttrNames[name] = displayAttributeName(name)
		if len(displayAttrNames[name]) > attrNameLen {
			attrNameLen = len(displayAttrNames[name])
		}
	}
	sort.Strings(attrNames)
	if len(attrNames) == 0 {
		return false
	}

	for _, name := range attrNames {
		attrS := attrsS[name]
		oldVal := ctyGetAttrMaybeNull(old, name)
		newVal := ctyGetAttrMaybeNull(new, name)

		result.bodyWritten = true
		skipped := p.writeAttrDiff(displayAttrNames[name], attrS, oldVal, newVal, attrNameLen, indent, path)
		if skipped {
			result.skippedAttributes++
		}
	}

	return true
}

// getPlanActionAndShow returns the action value
// and a boolean for showJustNew. In this function we
// modify the old and new values to remove any possible marks
func getPlanActionAndShow(old cty.Value, new cty.Value) (plans.Action, bool) {
	var action plans.Action
	showJustNew := false
	switch {
	case old.IsNull():
		action = plans.Create
		showJustNew = true
	case new.IsNull():
		action = plans.Delete
	case ctyEqualWithUnknown(old, new):
		action = plans.NoOp
		showJustNew = true
	default:
		action = plans.Update
	}
	return action, showJustNew
}

func (p *blockBodyDiffPrinter) writeAttrDiff(name string, attrS *configschema.Attribute, old, new cty.Value, nameLen, indent int, path cty.Path) bool {
	path = append(path, cty.GetAttrStep{Name: name})
	action, showJustNew := getPlanActionAndShow(old, new)

	if action == plans.NoOp && !p.verbose && !identifyingAttribute(name, attrS) {
		return true
	}

	if attrS.NestedType != nil {
		p.writeNestedAttrDiff(name, attrS, old, new, nameLen, indent, path, action, showJustNew)
		return false
	}

	p.buf.WriteString("\n")

	p.writeSensitivityWarning(old, new, indent, action, false)

	p.buf.WriteString(strings.Repeat(" ", indent))
	p.writeActionSymbol(action)

	p.buf.WriteString(p.color.Color("[bold]"))
	p.buf.WriteString(name)
	p.buf.WriteString(p.color.Color("[reset]"))
	p.buf.WriteString(strings.Repeat(" ", nameLen-len(name)))
	p.buf.WriteString(" = ")

	if attrS.Sensitive {
		p.buf.WriteString(sensitiveCaption)
		if p.pathForcesNewResource(path) {
			p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
		}
	} else {
		switch {
		case showJustNew:
			p.writeValue(new, action, indent+2)
			if p.pathForcesNewResource(path) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
		default:
			// We show new even if it is null to emphasize the fact
			// that it is being unset, since otherwise it is easy to
			// misunderstand that the value is still set to the old value.
			p.writeValueDiff(old, new, indent+2, path)
		}
	}

	return false
}

// writeNestedAttrDiff is responsible for formatting Attributes with NestedTypes
// in the diff.
func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
	name string, attrWithNestedS *configschema.Attribute, old, new cty.Value,
	nameLen, indent int, path cty.Path, action plans.Action, showJustNew bool) {

	objS := attrWithNestedS.NestedType

	p.buf.WriteString("\n")
	p.writeSensitivityWarning(old, new, indent, action, false)
	p.buf.WriteString(strings.Repeat(" ", indent))
	p.writeActionSymbol(action)

	p.buf.WriteString(p.color.Color("[bold]"))
	p.buf.WriteString(name)
	p.buf.WriteString(p.color.Color("[reset]"))
	p.buf.WriteString(strings.Repeat(" ", nameLen-len(name)))

	// Then schema of the attribute itself can be marked sensitive, or the values assigned
	sensitive := attrWithNestedS.Sensitive || old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive)
	if sensitive {
		p.buf.WriteString(" = ")
		p.buf.WriteString(sensitiveCaption)

		if p.pathForcesNewResource(path) {
			p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
		}
		return
	}

	result := &blockBodyDiffResult{}
	switch objS.Nesting {
	case configschema.NestingSingle:
		p.buf.WriteString(" = {")
		if action != plans.NoOp && (p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1])) {
			p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
		}
		p.writeAttrsDiff(objS.Attributes, old, new, indent+4, path, result)
		p.writeSkippedAttr(result.skippedAttributes, indent+6)
		p.buf.WriteString("\n")
		p.buf.WriteString(strings.Repeat(" ", indent+2))
		p.buf.WriteString("}")

		if !new.IsKnown() {
			p.buf.WriteString(" -> (known after apply)")
		} else if new.IsNull() {
			p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
		}

	case configschema.NestingList:
		p.buf.WriteString(" = [")
		if action != plans.NoOp && (p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1])) {
			p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
		}
		p.buf.WriteString("\n")

		oldItems := ctyCollectionValues(old)
		newItems := ctyCollectionValues(new)
		// Here we intentionally preserve the index-based correspondance
		// between old and new, rather than trying to detect insertions
		// and removals in the list, because this more accurately reflects
		// how Terraform Core and providers will understand the change,
		// particularly when the nested block contains computed attributes
		// that will themselves maintain correspondance by index.

		// commonLen is number of elements that exist in both lists, which
		// will be presented as updates (~). Any additional items in one
		// of the lists will be presented as either creates (+) or deletes (-)
		// depending on which list they belong to. maxLen is the number of
		// elements in that longer list.
		var commonLen int
		var maxLen int
		// unchanged is the number of unchanged elements
		var unchanged int

		switch {
		case len(oldItems) < len(newItems):
			commonLen = len(oldItems)
			maxLen = len(newItems)
		default:
			commonLen = len(newItems)
			maxLen = len(oldItems)
		}
		for i := 0; i < maxLen; i++ {
			path := append(path, cty.IndexStep{Key: cty.NumberIntVal(int64(i))})

			var action plans.Action
			var oldItem, newItem cty.Value
			switch {
			case i < commonLen:
				oldItem = oldItems[i]
				newItem = newItems[i]
				if oldItem.RawEquals(newItem) {
					action = plans.NoOp
					unchanged++
				} else {
					action = plans.Update
				}
			case i < len(oldItems):
				oldItem = oldItems[i]
				newItem = cty.NullVal(oldItem.Type())
				action = plans.Delete
			case i < len(newItems):
				newItem = newItems[i]
				oldItem = cty.NullVal(newItem.Type())
				action = plans.Create
			default:
				action = plans.NoOp
			}

			if action != plans.NoOp {
				p.buf.WriteString(strings.Repeat(" ", indent+4))
				p.writeActionSymbol(action)
				p.buf.WriteString("{")

				result := &blockBodyDiffResult{}
				p.writeAttrsDiff(objS.Attributes, oldItem, newItem, indent+8, path, result)
				if action == plans.Update {
					p.writeSkippedAttr(result.skippedAttributes, indent+10)
				}
				p.buf.WriteString("\n")

				p.buf.WriteString(strings.Repeat(" ", indent+6))
				p.buf.WriteString("},\n")
			}
		}
		p.writeSkippedElems(unchanged, indent+6)
		p.buf.WriteString(strings.Repeat(" ", indent+2))
		p.buf.WriteString("]")

		if !new.IsKnown() {
			p.buf.WriteString(" -> (known after apply)")
		} else if new.IsNull() {
			p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
		}

	case configschema.NestingSet:
		oldItems := ctyCollectionValues(old)
		newItems := ctyCollectionValues(new)

		var all cty.Value
		if len(oldItems)+len(newItems) > 0 {
			allItems := make([]cty.Value, 0, len(oldItems)+len(newItems))
			allItems = append(allItems, oldItems...)
			allItems = append(allItems, newItems...)

			all = cty.SetVal(allItems)
		} else {
			all = cty.SetValEmpty(old.Type().ElementType())
		}

		p.buf.WriteString(" = [")

		var unchanged int

		for it := all.ElementIterator(); it.Next(); {
			_, val := it.Element()
			var action plans.Action
			var oldValue, newValue cty.Value
			switch {
			case !val.IsKnown():
				action = plans.Update
				newValue = val
			case !new.IsKnown():
				action = plans.Delete
				// the value must have come from the old set
				oldValue = val
				// Mark the new val as null, but the entire set will be
				// displayed as "(unknown after apply)"
				newValue = cty.NullVal(val.Type())
			case old.IsNull() || !old.HasElement(val).True():
				action = plans.Create
				oldValue = cty.NullVal(val.Type())
				newValue = val
			case new.IsNull() || !new.HasElement(val).True():
				action = plans.Delete
				oldValue = val
				newValue = cty.NullVal(val.Type())
			default:
				action = plans.NoOp
				oldValue = val
				newValue = val
			}

			if action == plans.NoOp {
				unchanged++
				continue
			}

			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent+4))
			p.writeActionSymbol(action)
			p.buf.WriteString("{")

			if p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1]) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}

			path := append(path, cty.IndexStep{Key: val})
			p.writeAttrsDiff(objS.Attributes, oldValue, newValue, indent+8, path, result)

			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent+6))
			p.buf.WriteString("},")
		}
		p.buf.WriteString("\n")
		p.writeSkippedElems(unchanged, indent+6)
		p.buf.WriteString(strings.Repeat(" ", indent+2))
		p.buf.WriteString("]")

		if !new.IsKnown() {
			p.buf.WriteString(" -> (known after apply)")
		} else if new.IsNull() {
			p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
		}

	case configschema.NestingMap:
		// For the sake of handling nested blocks, we'll treat a null map
		// the same as an empty map since the config language doesn't
		// distinguish these anyway.
		old = ctyNullBlockMapAsEmpty(old)
		new = ctyNullBlockMapAsEmpty(new)

		oldItems := old.AsValueMap()

		newItems := map[string]cty.Value{}

		if new.IsKnown() {
			newItems = new.AsValueMap()
		}

		allKeys := make(map[string]bool)
		for k := range oldItems {
			allKeys[k] = true
		}
		for k := range newItems {
			allKeys[k] = true
		}
		allKeysOrder := make([]string, 0, len(allKeys))
		for k := range allKeys {
			allKeysOrder = append(allKeysOrder, k)
		}
		sort.Strings(allKeysOrder)

		p.buf.WriteString(" = {\n")

		// unchanged tracks the number of unchanged elements
		unchanged := 0
		for _, k := range allKeysOrder {
			var action plans.Action
			oldValue := oldItems[k]

			newValue := newItems[k]
			switch {
			case oldValue == cty.NilVal:
				oldValue = cty.NullVal(newValue.Type())
				action = plans.Create
			case newValue == cty.NilVal:
				newValue = cty.NullVal(oldValue.Type())
				action = plans.Delete
			case !newValue.RawEquals(oldValue):
				action = plans.Update
			default:
				action = plans.NoOp
				unchanged++
			}

			if action != plans.NoOp {
				p.buf.WriteString(strings.Repeat(" ", indent+4))
				p.writeActionSymbol(action)
				fmt.Fprintf(p.buf, "%q = {", k)
				if p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1]) {
					p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
				}

				path := append(path, cty.IndexStep{Key: cty.StringVal(k)})
				p.writeAttrsDiff(objS.Attributes, oldValue, newValue, indent+8, path, result)
				p.writeSkippedAttr(result.skippedAttributes, indent+10)
				p.buf.WriteString("\n")
				p.buf.WriteString(strings.Repeat(" ", indent+6))
				p.buf.WriteString("},\n")
			}
		}

		p.writeSkippedElems(unchanged, indent+6)
		p.buf.WriteString(strings.Repeat(" ", indent+2))
		p.buf.WriteString("}")
		if !new.IsKnown() {
			p.buf.WriteString(" -> (known after apply)")
		} else if new.IsNull() {
			p.buf.WriteString(p.color.Color("[dark_gray] -> null[reset]"))
		}
	}
}

func (p *blockBodyDiffPrinter) writeNestedBlockDiffs(name string, blockS *configschema.NestedBlock, old, new cty.Value, blankBefore bool, indent int, path cty.Path) int {
	skippedBlocks := 0
	path = append(path, cty.GetAttrStep{Name: name})
	if old.IsNull() && new.IsNull() {
		// Nothing to do if both old and new is null
		return skippedBlocks
	}

	// If either the old or the new value is marked,
	// Display a special diff because it is irrelevant
	// to list all obfuscated attributes as (sensitive value)
	if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
		p.writeSensitiveNestedBlockDiff(name, old, new, indent, blankBefore, path)
		return 0
	}

	// Where old/new are collections representing a nesting mode other than
	// NestingSingle, we assume the collection value can never be unknown
	// since we always produce the container for the nested objects, even if
	// the objects within are computed.

	switch blockS.Nesting {
	case configschema.NestingSingle, configschema.NestingGroup:
		var action plans.Action
		eqV := new.Equals(old)
		switch {
		case old.IsNull():
			action = plans.Create
		case new.IsNull():
			action = plans.Delete
		case !new.IsWhollyKnown() || !old.IsWhollyKnown():
			// "old" should actually always be known due to our contract
			// that old values must never be unknown, but we'll allow it
			// anyway to be robust.
			action = plans.Update
		case !eqV.IsKnown() || !eqV.True():
			action = plans.Update
		}

		skipped := p.writeNestedBlockDiff(name, nil, &blockS.Block, action, old, new, indent, blankBefore, path)
		if skipped {
			return 1
		}
	case configschema.NestingList:
		// For the sake of handling nested blocks, we'll treat a null list
		// the same as an empty list since the config language doesn't
		// distinguish these anyway.
		old = ctyNullBlockListAsEmpty(old)
		new = ctyNullBlockListAsEmpty(new)

		oldItems := ctyCollectionValues(old)
		newItems := ctyCollectionValues(new)

		// Here we intentionally preserve the index-based correspondance
		// between old and new, rather than trying to detect insertions
		// and removals in the list, because this more accurately reflects
		// how Terraform Core and providers will understand the change,
		// particularly when the nested block contains computed attributes
		// that will themselves maintain correspondance by index.

		// commonLen is number of elements that exist in both lists, which
		// will be presented as updates (~). Any additional items in one
		// of the lists will be presented as either creates (+) or deletes (-)
		// depending on which list they belong to.
		var commonLen int
		switch {
		case len(oldItems) < len(newItems):
			commonLen = len(oldItems)
		default:
			commonLen = len(newItems)
		}

		blankBeforeInner := blankBefore
		for i := 0; i < commonLen; i++ {
			path := append(path, cty.IndexStep{Key: cty.NumberIntVal(int64(i))})
			oldItem := oldItems[i]
			newItem := newItems[i]
			action := plans.Update
			if oldItem.RawEquals(newItem) {
				action = plans.NoOp
			}
			skipped := p.writeNestedBlockDiff(name, nil, &blockS.Block, action, oldItem, newItem, indent, blankBeforeInner, path)
			if skipped {
				skippedBlocks++
			} else {
				blankBeforeInner = false
			}
		}
		for i := commonLen; i < len(oldItems); i++ {
			path := append(path, cty.IndexStep{Key: cty.NumberIntVal(int64(i))})
			oldItem := oldItems[i]
			newItem := cty.NullVal(oldItem.Type())
			skipped := p.writeNestedBlockDiff(name, nil, &blockS.Block, plans.Delete, oldItem, newItem, indent, blankBeforeInner, path)
			if skipped {
				skippedBlocks++
			} else {
				blankBeforeInner = false
			}
		}
		for i := commonLen; i < len(newItems); i++ {
			path := append(path, cty.IndexStep{Key: cty.NumberIntVal(int64(i))})
			newItem := newItems[i]
			oldItem := cty.NullVal(newItem.Type())
			skipped := p.writeNestedBlockDiff(name, nil, &blockS.Block, plans.Create, oldItem, newItem, indent, blankBeforeInner, path)
			if skipped {
				skippedBlocks++
			} else {
				blankBeforeInner = false
			}
		}
	case configschema.NestingSet:
		// For the sake of handling nested blocks, we'll treat a null set
		// the same as an empty set since the config language doesn't
		// distinguish these anyway.
		old = ctyNullBlockSetAsEmpty(old)
		new = ctyNullBlockSetAsEmpty(new)

		oldItems := ctyCollectionValues(old)
		newItems := ctyCollectionValues(new)

		if (len(oldItems) + len(newItems)) == 0 {
			// Nothing to do if both sets are empty
			return 0
		}

		allItems := make([]cty.Value, 0, len(oldItems)+len(newItems))
		allItems = append(allItems, oldItems...)
		allItems = append(allItems, newItems...)
		all := cty.SetVal(allItems)

		blankBeforeInner := blankBefore
		for it := all.ElementIterator(); it.Next(); {
			_, val := it.Element()
			var action plans.Action
			var oldValue, newValue cty.Value
			switch {
			case !val.IsKnown():
				action = plans.Update
				newValue = val
			case !old.HasElement(val).True():
				action = plans.Create
				oldValue = cty.NullVal(val.Type())
				newValue = val
			case !new.HasElement(val).True():
				action = plans.Delete
				oldValue = val
				newValue = cty.NullVal(val.Type())
			default:
				action = plans.NoOp
				oldValue = val
				newValue = val
			}
			path := append(path, cty.IndexStep{Key: val})
			skipped := p.writeNestedBlockDiff(name, nil, &blockS.Block, action, oldValue, newValue, indent, blankBeforeInner, path)
			if skipped {
				skippedBlocks++
			} else {
				blankBeforeInner = false
			}
		}

	case configschema.NestingMap:
		// For the sake of handling nested blocks, we'll treat a null map
		// the same as an empty map since the config language doesn't
		// distinguish these anyway.
		old = ctyNullBlockMapAsEmpty(old)
		new = ctyNullBlockMapAsEmpty(new)

		oldItems := old.AsValueMap()
		newItems := new.AsValueMap()
		if (len(oldItems) + len(newItems)) == 0 {
			// Nothing to do if both maps are empty
			return 0
		}

		allKeys := make(map[string]bool)
		for k := range oldItems {
			allKeys[k] = true
		}
		for k := range newItems {
			allKeys[k] = true
		}
		allKeysOrder := make([]string, 0, len(allKeys))
		for k := range allKeys {
			allKeysOrder = append(allKeysOrder, k)
		}
		sort.Strings(allKeysOrder)

		blankBeforeInner := blankBefore
		for _, k := range allKeysOrder {
			var action plans.Action
			oldValue := oldItems[k]
			newValue := newItems[k]
			switch {
			case oldValue == cty.NilVal:
				oldValue = cty.NullVal(newValue.Type())
				action = plans.Create
			case newValue == cty.NilVal:
				newValue = cty.NullVal(oldValue.Type())
				action = plans.Delete
			case !newValue.RawEquals(oldValue):
				action = plans.Update
			default:
				action = plans.NoOp
			}

			path := append(path, cty.IndexStep{Key: cty.StringVal(k)})
			skipped := p.writeNestedBlockDiff(name, &k, &blockS.Block, action, oldValue, newValue, indent, blankBeforeInner, path)
			if skipped {
				skippedBlocks++
			} else {
				blankBeforeInner = false
			}
		}
	}
	return skippedBlocks
}

func (p *blockBodyDiffPrinter) writeSensitiveNestedBlockDiff(name string, old, new cty.Value, indent int, blankBefore bool, path cty.Path) {
	var action plans.Action
	switch {
	case old.IsNull():
		action = plans.Create
	case new.IsNull():
		action = plans.Delete
	case !new.IsWhollyKnown() || !old.IsWhollyKnown():
		// "old" should actually always be known due to our contract
		// that old values must never be unknown, but we'll allow it
		// anyway to be robust.
		action = plans.Update
	case !ctyEqualValueAndMarks(old, new):
		action = plans.Update
	}

	if blankBefore {
		p.buf.WriteRune('\n')
	}

	// New line before warning printing
	p.buf.WriteRune('\n')
	p.writeSensitivityWarning(old, new, indent, action, true)
	p.buf.WriteString(strings.Repeat(" ", indent))
	p.writeActionSymbol(action)
	fmt.Fprintf(p.buf, "%s {", name)
	if action != plans.NoOp && p.pathForcesNewResource(path) {
		p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
	}
	p.buf.WriteRune('\n')
	p.buf.WriteString(strings.Repeat(" ", indent+4))
	p.buf.WriteString("# At least one attribute in this block is (or was) sensitive,\n")
	p.buf.WriteString(strings.Repeat(" ", indent+4))
	p.buf.WriteString("# so its contents will not be displayed.")
	p.buf.WriteRune('\n')
	p.buf.WriteString(strings.Repeat(" ", indent+2))
	p.buf.WriteString("}")
}

func (p *blockBodyDiffPrinter) writeNestedBlockDiff(name string, label *string, blockS *configschema.Block, action plans.Action, old, new cty.Value, indent int, blankBefore bool, path cty.Path) bool {
	if action == plans.NoOp && !p.verbose {
		return true
	}

	if blankBefore {
		p.buf.WriteRune('\n')
	}

	p.buf.WriteString("\n")
	p.buf.WriteString(strings.Repeat(" ", indent))
	p.writeActionSymbol(action)

	if label != nil {
		fmt.Fprintf(p.buf, "%s %q {", name, *label)
	} else {
		fmt.Fprintf(p.buf, "%s {", name)
	}

	if action != plans.NoOp && (p.pathForcesNewResource(path) || p.pathForcesNewResource(path[:len(path)-1])) {
		p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
	}

	result := p.writeBlockBodyDiff(blockS, old, new, indent+4, path)
	if result.bodyWritten {
		p.buf.WriteString("\n")
		p.buf.WriteString(strings.Repeat(" ", indent+2))
	}
	p.buf.WriteString("}")

	return false
}

func (p *blockBodyDiffPrinter) writeValue(val cty.Value, action plans.Action, indent int) {
	// Could check specifically for the sensitivity marker
	if val.HasMark(marks.Sensitive) {
		p.buf.WriteString(sensitiveCaption)
		return
	}

	if !val.IsKnown() {
		p.buf.WriteString("(known after apply)")
		return
	}
	if val.IsNull() {
		p.buf.WriteString(p.color.Color("[dark_gray]null[reset]"))
		return
	}

	ty := val.Type()

	switch {
	case ty.IsPrimitiveType():
		switch ty {
		case cty.String:
			{
				// Special behavior for JSON strings containing array or object
				src := []byte(val.AsString())
				ty, err := ctyjson.ImpliedType(src)
				// check for the special case of "null", which decodes to nil,
				// and just allow it to be printed out directly
				if err == nil && !ty.IsPrimitiveType() && strings.TrimSpace(val.AsString()) != "null" {
					jv, err := ctyjson.Unmarshal(src, ty)
					if err == nil {
						p.buf.WriteString("jsonencode(")
						if jv.LengthInt() == 0 {
							p.writeValue(jv, action, 0)
						} else {
							p.buf.WriteByte('\n')
							p.buf.WriteString(strings.Repeat(" ", indent+4))
							p.writeValue(jv, action, indent+4)
							p.buf.WriteByte('\n')
							p.buf.WriteString(strings.Repeat(" ", indent))
						}
						p.buf.WriteByte(')')
						break // don't *also* do the normal behavior below
					}
				}
			}

			if strings.Contains(val.AsString(), "\n") {
				// It's a multi-line string, so we want to use the multi-line
				// rendering so it'll be readable. Rather than re-implement
				// that here, we'll just re-use the multi-line string diff
				// printer with no changes, which ends up producing the
				// result we want here.
				// The path argument is nil because we don't track path
				// information into strings and we know that a string can't
				// have any indices or attributes that might need to be marked
				// as (requires replacement), which is what that argument is for.
				p.writeValueDiff(val, val, indent, nil)
				break
			}

			fmt.Fprintf(p.buf, "%q", val.AsString())
		case cty.Bool:
			if val.True() {
				p.buf.WriteString("true")
			} else {
				p.buf.WriteString("false")
			}
		case cty.Number:
			bf := val.AsBigFloat()
			p.buf.WriteString(bf.Text('f', -1))
		default:
			// should never happen, since the above is exhaustive
			fmt.Fprintf(p.buf, "%#v", val)
		}
	case ty.IsListType() || ty.IsSetType() || ty.IsTupleType():
		p.buf.WriteString("[")

		it := val.ElementIterator()
		for it.Next() {
			_, val := it.Element()

			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent+2))
			p.writeActionSymbol(action)
			p.writeValue(val, action, indent+4)
			p.buf.WriteString(",")
		}

		if val.LengthInt() > 0 {
			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent))
		}
		p.buf.WriteString("]")
	case ty.IsMapType():
		p.buf.WriteString("{")

		keyLen := 0
		for it := val.ElementIterator(); it.Next(); {
			key, _ := it.Element()
			if keyStr := key.AsString(); len(keyStr) > keyLen {
				keyLen = len(keyStr)
			}
		}

		for it := val.ElementIterator(); it.Next(); {
			key, val := it.Element()

			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent+2))
			p.writeActionSymbol(action)
			p.writeValue(key, action, indent+4)
			p.buf.WriteString(strings.Repeat(" ", keyLen-len(key.AsString())))
			p.buf.WriteString(" = ")
			p.writeValue(val, action, indent+4)
		}

		if val.LengthInt() > 0 {
			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent))
		}
		p.buf.WriteString("}")
	case ty.IsObjectType():
		p.buf.WriteString("{")

		atys := ty.AttributeTypes()
		attrNames := make([]string, 0, len(atys))
		displayAttrNames := make(map[string]string, len(atys))
		nameLen := 0
		for attrName := range atys {
			attrNames = append(attrNames, attrName)
			displayAttrNames[attrName] = displayAttributeName(attrName)
			if len(displayAttrNames[attrName]) > nameLen {
				nameLen = len(displayAttrNames[attrName])
			}
		}
		sort.Strings(attrNames)

		for _, attrName := range attrNames {
			val := val.GetAttr(attrName)
			displayAttrName := displayAttrNames[attrName]

			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent+2))
			p.writeActionSymbol(action)
			p.buf.WriteString(displayAttrName)
			p.buf.WriteString(strings.Repeat(" ", nameLen-len(displayAttrName)))
			p.buf.WriteString(" = ")
			p.writeValue(val, action, indent+4)
		}

		if len(attrNames) > 0 {
			p.buf.WriteString("\n")
			p.buf.WriteString(strings.Repeat(" ", indent))
		}
		p.buf.WriteString("}")
	}
}

func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, path cty.Path) {
	ty := old.Type()
	typesEqual := ctyTypesEqual(ty, new.Type())

	// We have some specialized diff implementations for certain complex
	// values where it's useful to see a visualization of the diff of
	// the nested elements rather than just showing the entire old and
	// new values verbatim.
	// However, these specialized implementations can apply only if both
	// values are known and non-null.
	if old.IsKnown() && new.IsKnown() && !old.IsNull() && !new.IsNull() && typesEqual {
		if old.HasMark(marks.Sensitive) || new.HasMark(marks.Sensitive) {
			p.buf.WriteString(sensitiveCaption)
			if p.pathForcesNewResource(path) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
			return
		}

		switch {
		case ty == cty.String:
			// We have special behavior for both multi-line strings in general
			// and for strings that can parse as JSON. For the JSON handling
			// to apply, both old and new must be valid JSON.
			// For single-line strings that don't parse as JSON we just fall
			// out of this switch block and do the default old -> new rendering.
			oldS := old.AsString()
			newS := new.AsString()

			{
				// Special behavior for JSON strings containing object or
				// list values.
				oldBytes := []byte(oldS)
				newBytes := []byte(newS)
				oldType, oldErr := ctyjson.ImpliedType(oldBytes)
				newType, newErr := ctyjson.ImpliedType(newBytes)
				if oldErr == nil && newErr == nil && !(oldType.IsPrimitiveType() && newType.IsPrimitiveType()) {
					oldJV, oldErr := ctyjson.Unmarshal(oldBytes, oldType)
					newJV, newErr := ctyjson.Unmarshal(newBytes, newType)
					if oldErr == nil && newErr == nil {
						if !oldJV.RawEquals(newJV) { // two JSON values may differ only in insignificant whitespace
							p.buf.WriteString("jsonencode(")
							p.buf.WriteByte('\n')
							p.buf.WriteString(strings.Repeat(" ", indent+2))
							p.writeActionSymbol(plans.Update)
							p.writeValueDiff(oldJV, newJV, indent+4, path)
							p.buf.WriteByte('\n')
							p.buf.WriteString(strings.Repeat(" ", indent))
							p.buf.WriteByte(')')
						} else {
							// if they differ only in insignificant whitespace
							// then we'll note that but still expand out the
							// effective value.
							if p.pathForcesNewResource(path) {
								p.buf.WriteString(p.color.Color("jsonencode( [red]# whitespace changes force replacement[reset]"))
							} else {
								p.buf.WriteString(p.color.Color("jsonencode( [dim]# whitespace changes[reset]"))
							}
							p.buf.WriteByte('\n')
							p.buf.WriteString(strings.Repeat(" ", indent+4))
							p.writeValue(oldJV, plans.NoOp, indent+4)
							p.buf.WriteByte('\n')
							p.buf.WriteString(strings.Repeat(" ", indent))
							p.buf.WriteByte(')')
						}
						return
					}
				}
			}

			if !strings.Contains(oldS, "\n") && !strings.Contains(newS, "\n") {
				break
			}

			p.buf.WriteString("<<-EOT")
			if p.pathForcesNewResource(path) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
			p.buf.WriteString("\n")

			var oldLines, newLines []cty.Value
			{
				r := strings.NewReader(oldS)
				sc := bufio.NewScanner(r)
				for sc.Scan() {
					oldLines = append(oldLines, cty.StringVal(sc.Text()))
				}
			}
			{
				r := strings.NewReader(newS)
				sc := bufio.NewScanner(r)
				for sc.Scan() {
					newLines = append(newLines, cty.StringVal(sc.Text()))
				}
			}

			// Optimization for strings which are exactly equal: just print
			// directly without calculating the sequence diff. This makes a
			// significant difference when this code path is reached via a
			// writeValue call with a large multi-line string.
			if oldS == newS {
				for _, line := range newLines {
					p.buf.WriteString(strings.Repeat(" ", indent+4))
					p.buf.WriteString(line.AsString())
					p.buf.WriteString("\n")
				}
			} else {
				diffLines := ctySequenceDiff(oldLines, newLines)
				for _, diffLine := range diffLines {
					p.buf.WriteString(strings.Repeat(" ", indent+2))
					p.writeActionSymbol(diffLine.Action)

					switch diffLine.Action {
					case plans.NoOp, plans.Delete:
						p.buf.WriteString(diffLine.Before.AsString())
					case plans.Create:
						p.buf.WriteString(diffLine.After.AsString())
					default:
						// Should never happen since the above covers all
						// actions that ctySequenceDiff can return for strings
						p.buf.WriteString(diffLine.After.AsString())

					}
					p.buf.WriteString("\n")
				}
			}

			p.buf.WriteString(strings.Repeat(" ", indent)) // +4 here because there's no symbol
			p.buf.WriteString("EOT")

			return

		case ty.IsSetType():
			p.buf.WriteString("[")
			if p.pathForcesNewResource(path) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
			p.buf.WriteString("\n")

			var addedVals, removedVals, allVals []cty.Value
			for it := old.ElementIterator(); it.Next(); {
				_, val := it.Element()
				allVals = append(allVals, val)
				if new.HasElement(val).False() {
					removedVals = append(removedVals, val)
				}
			}
			for it := new.ElementIterator(); it.Next(); {
				_, val := it.Element()
				allVals = append(allVals, val)
				if val.IsKnown() && old.HasElement(val).False() {
					addedVals = append(addedVals, val)
				}
			}

			var all, added, removed cty.Value
			if len(allVals) > 0 {
				all = cty.SetVal(allVals)
			} else {
				all = cty.SetValEmpty(ty.ElementType())
			}
			if len(addedVals) > 0 {
				added = cty.SetVal(addedVals)
			} else {
				added = cty.SetValEmpty(ty.ElementType())
			}
			if len(removedVals) > 0 {
				removed = cty.SetVal(removedVals)
			} else {
				removed = cty.SetValEmpty(ty.ElementType())
			}

			suppressedElements := 0
			for it := all.ElementIterator(); it.Next(); {
				_, val := it.Element()

				var action plans.Action
				switch {
				case !val.IsKnown():
					action = plans.Update
				case added.HasElement(val).True():
					action = plans.Create
				case removed.HasElement(val).True():
					action = plans.Delete
				default:
					action = plans.NoOp
				}

				if action == plans.NoOp && !p.verbose {
					suppressedElements++
					continue
				}

				p.buf.WriteString(strings.Repeat(" ", indent+2))
				p.writeActionSymbol(action)
				p.writeValue(val, action, indent+4)
				p.buf.WriteString(",\n")
			}

			if suppressedElements > 0 {
				p.writeActionSymbol(plans.NoOp)
				p.buf.WriteString(strings.Repeat(" ", indent+2))
				noun := "elements"
				if suppressedElements == 1 {
					noun = "element"
				}
				p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), suppressedElements, noun))
				p.buf.WriteString("\n")
			}

			p.buf.WriteString(strings.Repeat(" ", indent))
			p.buf.WriteString("]")
			return
		case ty.IsListType() || ty.IsTupleType():
			p.buf.WriteString("[")
			if p.pathForcesNewResource(path) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
			p.buf.WriteString("\n")

			elemDiffs := ctySequenceDiff(old.AsValueSlice(), new.AsValueSlice())

			// Maintain a stack of suppressed lines in the diff for later
			// display or elision
			var suppressedElements []*plans.Change
			var changeShown bool

			for i := 0; i < len(elemDiffs); i++ {
				if !p.verbose {
					for i < len(elemDiffs) && elemDiffs[i].Action == plans.NoOp {
						suppressedElements = append(suppressedElements, elemDiffs[i])
						i++
					}
				}

				// If we have some suppressed elements on the stack…
				if len(suppressedElements) > 0 {
					// If we've just rendered a change, display the first
					// element in the stack as context
					if changeShown {
						elemDiff := suppressedElements[0]
						p.buf.WriteString(strings.Repeat(" ", indent+4))
						p.writeValue(elemDiff.After, elemDiff.Action, indent+4)
						p.buf.WriteString(",\n")
						suppressedElements = suppressedElements[1:]
					}

					hidden := len(suppressedElements)

					// If we're not yet at the end of the list, capture the
					// last element on the stack as context for the upcoming
					// change to be rendered
					var nextContextDiff *plans.Change
					if hidden > 0 && i < len(elemDiffs) {
						hidden--
						nextContextDiff = suppressedElements[hidden]
					}

					// If there are still hidden elements, show an elision
					// statement counting them
					if hidden > 0 {
						p.writeActionSymbol(plans.NoOp)
						p.buf.WriteString(strings.Repeat(" ", indent+2))
						noun := "elements"
						if hidden == 1 {
							noun = "element"
						}
						p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), hidden, noun))
						p.buf.WriteString("\n")
					}

					// Display the next context diff if it was captured above
					if nextContextDiff != nil {
						p.buf.WriteString(strings.Repeat(" ", indent+4))
						p.writeValue(nextContextDiff.After, nextContextDiff.Action, indent+4)
						p.buf.WriteString(",\n")
					}

					// Suppressed elements have now been handled so clear them again
					suppressedElements = nil
				}

				if i >= len(elemDiffs) {
					break
				}

				elemDiff := elemDiffs[i]
				p.buf.WriteString(strings.Repeat(" ", indent+2))
				p.writeActionSymbol(elemDiff.Action)
				switch elemDiff.Action {
				case plans.NoOp, plans.Delete:
					p.writeValue(elemDiff.Before, elemDiff.Action, indent+4)
				case plans.Update:
					p.writeValueDiff(elemDiff.Before, elemDiff.After, indent+4, path)
				case plans.Create:
					p.writeValue(elemDiff.After, elemDiff.Action, indent+4)
				default:
					// Should never happen since the above covers all
					// actions that ctySequenceDiff can return.
					p.writeValue(elemDiff.After, elemDiff.Action, indent+4)
				}

				p.buf.WriteString(",\n")
				changeShown = true
			}

			p.buf.WriteString(strings.Repeat(" ", indent))
			p.buf.WriteString("]")

			return

		case ty.IsMapType():
			p.buf.WriteString("{")
			if p.pathForcesNewResource(path) {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
			p.buf.WriteString("\n")

			var allKeys []string
			keyLen := 0
			for it := old.ElementIterator(); it.Next(); {
				k, _ := it.Element()
				keyStr := k.AsString()
				allKeys = append(allKeys, keyStr)
				if len(keyStr) > keyLen {
					keyLen = len(keyStr)
				}
			}
			for it := new.ElementIterator(); it.Next(); {
				k, _ := it.Element()
				keyStr := k.AsString()
				allKeys = append(allKeys, keyStr)
				if len(keyStr) > keyLen {
					keyLen = len(keyStr)
				}
			}

			sort.Strings(allKeys)

			suppressedElements := 0
			lastK := ""
			for i, k := range allKeys {
				if i > 0 && lastK == k {
					continue // skip duplicates (list is sorted)
				}
				lastK = k

				kV := cty.StringVal(k)
				var action plans.Action
				if old.HasIndex(kV).False() {
					action = plans.Create
				} else if new.HasIndex(kV).False() {
					action = plans.Delete
				}

				if old.HasIndex(kV).True() && new.HasIndex(kV).True() {
					if ctyEqualValueAndMarks(old.Index(kV), new.Index(kV)) {
						action = plans.NoOp
					} else {
						action = plans.Update
					}
				}

				if action == plans.NoOp && !p.verbose {
					suppressedElements++
					continue
				}

				path := append(path, cty.IndexStep{Key: kV})

				oldV := old.Index(kV)
				newV := new.Index(kV)
				p.writeSensitivityWarning(oldV, newV, indent+2, action, false)

				p.buf.WriteString(strings.Repeat(" ", indent+2))
				p.writeActionSymbol(action)
				p.writeValue(cty.StringVal(k), action, indent+4)
				p.buf.WriteString(strings.Repeat(" ", keyLen-len(k)))
				p.buf.WriteString(" = ")
				switch action {
				case plans.Create, plans.NoOp:
					v := new.Index(kV)
					if v.HasMark(marks.Sensitive) {
						p.buf.WriteString(sensitiveCaption)
					} else {
						p.writeValue(v, action, indent+4)
					}
				case plans.Delete:
					oldV := old.Index(kV)
					newV := cty.NullVal(oldV.Type())
					p.writeValueDiff(oldV, newV, indent+4, path)
				default:
					if oldV.HasMark(marks.Sensitive) || newV.HasMark(marks.Sensitive) {
						p.buf.WriteString(sensitiveCaption)
					} else {
						p.writeValueDiff(oldV, newV, indent+4, path)
					}
				}

				p.buf.WriteByte('\n')
			}

			if suppressedElements > 0 {
				p.writeActionSymbol(plans.NoOp)
				p.buf.WriteString(strings.Repeat(" ", indent+2))
				noun := "elements"
				if suppressedElements == 1 {
					noun = "element"
				}
				p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), suppressedElements, noun))
				p.buf.WriteString("\n")
			}

			p.buf.WriteString(strings.Repeat(" ", indent))
			p.buf.WriteString("}")

			return
		case ty.IsObjectType():
			p.buf.WriteString("{")
			p.buf.WriteString("\n")

			forcesNewResource := p.pathForcesNewResource(path)

			var allKeys []string
			displayKeys := make(map[string]string)
			keyLen := 0
			for it := old.ElementIterator(); it.Next(); {
				k, _ := it.Element()
				keyStr := k.AsString()
				allKeys = append(allKeys, keyStr)
				displayKeys[keyStr] = displayAttributeName(keyStr)
				if len(displayKeys[keyStr]) > keyLen {
					keyLen = len(displayKeys[keyStr])
				}
			}
			for it := new.ElementIterator(); it.Next(); {
				k, _ := it.Element()
				keyStr := k.AsString()
				allKeys = append(allKeys, keyStr)
				displayKeys[keyStr] = displayAttributeName(keyStr)
				if len(displayKeys[keyStr]) > keyLen {
					keyLen = len(displayKeys[keyStr])
				}
			}

			sort.Strings(allKeys)

			suppressedElements := 0
			lastK := ""
			for i, k := range allKeys {
				if i > 0 && lastK == k {
					continue // skip duplicates (list is sorted)
				}
				lastK = k

				kV := k
				var action plans.Action
				if !old.Type().HasAttribute(kV) {
					action = plans.Create
				} else if !new.Type().HasAttribute(kV) {
					action = plans.Delete
				} else if ctyEqualValueAndMarks(old.GetAttr(kV), new.GetAttr(kV)) {
					action = plans.NoOp
				} else {
					action = plans.Update
				}

				// TODO: If in future we have a schema associated with this
				// object, we should pass the attribute's schema to
				// identifyingAttribute here.
				if action == plans.NoOp && !p.verbose && !identifyingAttribute(k, nil) {
					suppressedElements++
					continue
				}

				path := append(path, cty.GetAttrStep{Name: kV})

				p.buf.WriteString(strings.Repeat(" ", indent+2))
				p.writeActionSymbol(action)
				p.buf.WriteString(displayKeys[k])
				p.buf.WriteString(strings.Repeat(" ", keyLen-len(displayKeys[k])))
				p.buf.WriteString(" = ")

				switch action {
				case plans.Create, plans.NoOp:
					v := new.GetAttr(kV)
					p.writeValue(v, action, indent+4)
				case plans.Delete:
					oldV := old.GetAttr(kV)
					newV := cty.NullVal(oldV.Type())
					p.writeValueDiff(oldV, newV, indent+4, path)
				default:
					oldV := old.GetAttr(kV)
					newV := new.GetAttr(kV)
					p.writeValueDiff(oldV, newV, indent+4, path)
				}

				p.buf.WriteString("\n")
			}

			if suppressedElements > 0 {
				p.writeActionSymbol(plans.NoOp)
				p.buf.WriteString(strings.Repeat(" ", indent+2))
				noun := "elements"
				if suppressedElements == 1 {
					noun = "element"
				}
				p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), suppressedElements, noun))
				p.buf.WriteString("\n")
			}

			p.buf.WriteString(strings.Repeat(" ", indent))
			p.buf.WriteString("}")

			if forcesNewResource {
				p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
			}
			return
		}
	}

	// In all other cases, we just show the new and old values as-is
	p.writeValue(old, plans.Delete, indent)
	if new.IsNull() {
		p.buf.WriteString(p.color.Color(" [dark_gray]->[reset] "))
	} else {
		p.buf.WriteString(p.color.Color(" [yellow]->[reset] "))
	}

	p.writeValue(new, plans.Create, indent)
	if p.pathForcesNewResource(path) {
		p.buf.WriteString(p.color.Color(forcesNewResourceCaption))
	}
}

// writeActionSymbol writes a symbol to represent the given action, followed
// by a space.
//
// It only supports the actions that can be represented with a single character:
// Create, Delete, Update and NoAction.
func (p *blockBodyDiffPrinter) writeActionSymbol(action plans.Action) {
	switch action {
	case plans.Create:
		p.buf.WriteString(p.color.Color("[green]+[reset] "))
	case plans.Delete:
		p.buf.WriteString(p.color.Color("[red]-[reset] "))
	case plans.Update:
		p.buf.WriteString(p.color.Color("[yellow]~[reset] "))
	case plans.NoOp:
		p.buf.WriteString("  ")
	default:
		// Should never happen
		p.buf.WriteString(p.color.Color("? "))
	}
}

func (p *blockBodyDiffPrinter) writeSensitivityWarning(old, new cty.Value, indent int, action plans.Action, isBlock bool) {
	// Dont' show this warning for create or delete
	if action == plans.Create || action == plans.Delete {
		return
	}

	// Customize the warning based on if it is an attribute or block
	diffType := "attribute value"
	if isBlock {
		diffType = "block"
	}

	// If only attribute sensitivity is changing, clarify that the value is unchanged
	var valueUnchangedSuffix string
	if !isBlock {
		oldUnmarked, _ := old.UnmarkDeep()
		newUnmarked, _ := new.UnmarkDeep()
		if oldUnmarked.RawEquals(newUnmarked) {
			valueUnchangedSuffix = " The value is unchanged."
		}
	}

	if new.HasMark(marks.Sensitive) && !old.HasMark(marks.Sensitive) {
		p.buf.WriteString(strings.Repeat(" ", indent))
		p.buf.WriteString(fmt.Sprintf(p.color.Color("# [yellow]Warning:[reset] this %s will be marked as sensitive and will not\n"), diffType))
		p.buf.WriteString(strings.Repeat(" ", indent))
		p.buf.WriteString(fmt.Sprintf("# display in UI output after applying this change.%s\n", valueUnchangedSuffix))
	}

	// Note if changing this attribute will change its sensitivity
	if old.HasMark(marks.Sensitive) && !new.HasMark(marks.Sensitive) {
		p.buf.WriteString(strings.Repeat(" ", indent))
		p.buf.WriteString(fmt.Sprintf(p.color.Color("# [yellow]Warning:[reset] this %s will no longer be marked as sensitive\n"), diffType))
		p.buf.WriteString(strings.Repeat(" ", indent))
		p.buf.WriteString(fmt.Sprintf("# after applying this change.%s\n", valueUnchangedSuffix))
	}
}

func (p *blockBodyDiffPrinter) pathForcesNewResource(path cty.Path) bool {
	if !p.action.IsReplace() || p.requiredReplace.Empty() {
		// "requiredReplace" only applies when the instance is being replaced,
		// and we should only inspect that set if it is not empty
		return false
	}
	return p.requiredReplace.Has(path)
}

func ctyEmptyString(value cty.Value) bool {
	if !value.IsNull() && value.IsKnown() {
		valueType := value.Type()
		if valueType == cty.String && value.AsString() == "" {
			return true
		}
	}
	return false
}

func ctyGetAttrMaybeNull(val cty.Value, name string) cty.Value {
	attrType := val.Type().AttributeType(name)

	if val.IsNull() {
		return cty.NullVal(attrType)
	}

	// We treat "" as null here
	// as existing SDK doesn't support null yet.
	// This allows us to avoid spurious diffs
	// until we introduce null to the SDK.
	attrValue := val.GetAttr(name)
	// If the value is marked, the ctyEmptyString function will fail
	if !val.ContainsMarked() && ctyEmptyString(attrValue) {
		return cty.NullVal(attrType)
	}

	return attrValue
}

func ctyCollectionValues(val cty.Value) []cty.Value {
	if !val.IsKnown() || val.IsNull() {
		return nil
	}

	ret := make([]cty.Value, 0, val.LengthInt())
	for it := val.ElementIterator(); it.Next(); {
		_, value := it.Element()
		ret = append(ret, value)
	}
	return ret
}

// ctySequenceDiff returns differences between given sequences of cty.Value(s)
// in the form of Create, Delete, or Update actions (for objects).
func ctySequenceDiff(old, new []cty.Value) []*plans.Change {
	var ret []*plans.Change
	lcs := objchange.LongestCommonSubsequence(old, new, objchange.ValueEqual)
	var oldI, newI, lcsI int
	for oldI < len(old) || newI < len(new) || lcsI < len(lcs) {
		// We first process items in the old and new sequences which are not
		// equal to the current common sequence item.  Old items are marked as
		// deletions, and new items are marked as additions.
		//
		// There is an exception for deleted & created object items, which we
		// try to render as updates where that makes sense.
		for oldI < len(old) && (lcsI >= len(lcs) || !old[oldI].RawEquals(lcs[lcsI])) {
			// Render this as an object update if all of these are true:
			//
			// - the current old item is an object;
			// - there's a current new item which is also an object;
			// - either there are no common items left, or the current new item
			//   doesn't equal the current common item.
			//
			// Why do we need the the last clause? If we have current items in all
			// three sequences, and the current new item is equal to a common item,
			// then we should just need to advance the old item list and we'll
			// eventually find a common item matching both old and new.
			//
			// This combination of conditions allows us to render an object update
			// diff instead of a combination of delete old & create new.
			isObjectDiff := old[oldI].Type().IsObjectType() && newI < len(new) && new[newI].Type().IsObjectType() && (lcsI >= len(lcs) || !new[newI].RawEquals(lcs[lcsI]))
			if isObjectDiff {
				ret = append(ret, &plans.Change{
					Action: plans.Update,
					Before: old[oldI],
					After:  new[newI],
				})
				oldI++
				newI++ // we also consume the next "new" in this case
				continue
			}

			// Otherwise, this item is not part of the common sequence, so
			// render as a deletion.
			ret = append(ret, &plans.Change{
				Action: plans.Delete,
				Before: old[oldI],
				After:  cty.NullVal(old[oldI].Type()),
			})
			oldI++
		}
		for newI < len(new) && (lcsI >= len(lcs) || !new[newI].RawEquals(lcs[lcsI])) {
			ret = append(ret, &plans.Change{
				Action: plans.Create,
				Before: cty.NullVal(new[newI].Type()),
				After:  new[newI],
			})
			newI++
		}

		// When we've exhausted the old & new sequences of items which are not
		// in the common subsequence, we render a common item and continue.
		if lcsI < len(lcs) {
			ret = append(ret, &plans.Change{
				Action: plans.NoOp,
				Before: lcs[lcsI],
				After:  lcs[lcsI],
			})

			// All of our indexes advance together now, since the line
			// is common to all three sequences.
			lcsI++
			oldI++
			newI++
		}
	}
	return ret
}

// ctyEqualValueAndMarks checks equality of two possibly-marked values,
// considering partially-unknown values and equal values with different marks
// as inequal
func ctyEqualWithUnknown(old, new cty.Value) bool {
	if !old.IsWhollyKnown() || !new.IsWhollyKnown() {
		return false
	}
	return ctyEqualValueAndMarks(old, new)
}

// ctyEqualValueAndMarks checks equality of two possibly-marked values,
// considering equal values with different marks as inequal
func ctyEqualValueAndMarks(old, new cty.Value) bool {
	oldUnmarked, oldMarks := old.UnmarkDeep()
	newUnmarked, newMarks := new.UnmarkDeep()
	sameValue := oldUnmarked.Equals(newUnmarked)
	return sameValue.IsKnown() && sameValue.True() && oldMarks.Equal(newMarks)
}

// ctyTypesEqual checks equality of two types more loosely
// by avoiding checks of object/tuple elements
// as we render differences on element-by-element basis anyway
func ctyTypesEqual(oldT, newT cty.Type) bool {
	if oldT.IsObjectType() && newT.IsObjectType() {
		return true
	}
	if oldT.IsTupleType() && newT.IsTupleType() {
		return true
	}
	return oldT.Equals(newT)
}

func ctyEnsurePathCapacity(path cty.Path, minExtra int) cty.Path {
	if cap(path)-len(path) >= minExtra {
		return path
	}
	newCap := cap(path) * 2
	if newCap < (len(path) + minExtra) {
		newCap = len(path) + minExtra
	}
	newPath := make(cty.Path, len(path), newCap)
	copy(newPath, path)
	return newPath
}

// ctyNullBlockListAsEmpty either returns the given value verbatim if it is non-nil
// or returns an empty value of a suitable type to serve as a placeholder for it.
//
// In particular, this function handles the special situation where a "list" is
// actually represented as a tuple type where nested blocks contain
// dynamically-typed values.
func ctyNullBlockListAsEmpty(in cty.Value) cty.Value {
	if !in.IsNull() {
		return in
	}
	if ty := in.Type(); ty.IsListType() {
		return cty.ListValEmpty(ty.ElementType())
	}
	return cty.EmptyTupleVal // must need a tuple, then
}

// ctyNullBlockMapAsEmpty either returns the given value verbatim if it is non-nil
// or returns an empty value of a suitable type to serve as a placeholder for it.
//
// In particular, this function handles the special situation where a "map" is
// actually represented as an object type where nested blocks contain
// dynamically-typed values.
func ctyNullBlockMapAsEmpty(in cty.Value) cty.Value {
	if !in.IsNull() {
		return in
	}
	if ty := in.Type(); ty.IsMapType() {
		return cty.MapValEmpty(ty.ElementType())
	}
	return cty.EmptyObjectVal // must need an object, then
}

// ctyNullBlockSetAsEmpty either returns the given value verbatim if it is non-nil
// or returns an empty value of a suitable type to serve as a placeholder for it.
func ctyNullBlockSetAsEmpty(in cty.Value) cty.Value {
	if !in.IsNull() {
		return in
	}
	// Dynamically-typed attributes are not supported inside blocks backed by
	// sets, so our result here is always a set.
	return cty.SetValEmpty(in.Type().ElementType())
}

// DiffActionSymbol returns a string that, once passed through a
// colorstring.Colorize, will produce a result that can be written
// to a terminal to produce a symbol made of three printable
// characters, possibly interspersed with VT100 color codes.
func DiffActionSymbol(action plans.Action) string {
	switch action {
	case plans.DeleteThenCreate:
		return "[red]-[reset]/[green]+[reset]"
	case plans.CreateThenDelete:
		return "[green]+[reset]/[red]-[reset]"
	case plans.Create:
		return "  [green]+[reset]"
	case plans.Delete:
		return "  [red]-[reset]"
	case plans.Read:
		return " [cyan]<=[reset]"
	case plans.Update:
		return "  [yellow]~[reset]"
	case plans.NoOp:
		return "   "
	default:
		return "  ?"
	}
}

// Extremely coarse heuristic for determining whether or not a given attribute
// name is important for identifying a resource. In the future, this may be
// replaced by a flag in the schema, but for now this is likely to be good
// enough.
func identifyingAttribute(name string, attrSchema *configschema.Attribute) bool {
	return name == "id" || name == "tags" || name == "name"
}

func (p *blockBodyDiffPrinter) writeSkippedAttr(skipped, indent int) {
	if skipped > 0 {
		noun := "attributes"
		if skipped == 1 {
			noun = "attribute"
		}
		p.buf.WriteString("\n")
		p.buf.WriteString(strings.Repeat(" ", indent))
		p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), skipped, noun))
	}
}

func (p *blockBodyDiffPrinter) writeSkippedElems(skipped, indent int) {
	if skipped > 0 {
		noun := "elements"
		if skipped == 1 {
			noun = "element"
		}
		p.buf.WriteString(strings.Repeat(" ", indent))
		p.buf.WriteString(fmt.Sprintf(p.color.Color("[dark_gray]# (%d unchanged %s hidden)[reset]"), skipped, noun))
		p.buf.WriteString("\n")
	}
}

func displayAttributeName(name string) string {
	if !hclsyntax.ValidIdentifier(name) {
		return fmt.Sprintf("%q", name)
	}
	return name
}
