// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1

package computed

import (
	"github.com/mitchellh/colorstring"

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

// Diff captures the computed diff for a single block, element or attribute.
//
// It essentially merges common functionality across all types of changes,
// namely the replace logic and the action / change type. Any remaining
// behaviour can be offloaded to the renderer which will be unique for the
// various change types (eg. maps, objects, lists, blocks, primitives, etc.).
type Diff struct {
	// Renderer captures the uncommon functionality across the different kinds
	// of changes. Each type of change (lists, blocks, sets, etc.) will have a
	// unique renderer.
	Renderer DiffRenderer

	// Action is the action described by this change (such as create, delete,
	// update, etc.).
	Action plans.Action

	// Replace tells the Change that it should add the `# forces replacement`
	// suffix.
	//
	// Every single change could potentially add this suffix, so we embed it in
	// the change as common functionality instead of in the specific renderers.
	Replace bool
}

// NewDiff creates a new Diff object with the provided renderer, action and
// replace context.
func NewDiff(renderer DiffRenderer, action plans.Action, replace bool) Diff {
	return Diff{
		Renderer: renderer,
		Action:   action,
		Replace:  replace,
	}
}

// RenderHuman prints the Change into a human-readable string referencing the
// specified RenderOpts.
//
// If the returned string is a single line, then indent should be ignored.
//
// If the return string is multiple lines, then indent should be used to offset
// the beginning of all lines but the first by the specified amount.
func (diff Diff) RenderHuman(indent int, opts RenderHumanOpts) string {
	return diff.Renderer.RenderHuman(diff, indent, opts)
}

// WarningsHuman returns a list of strings that should be rendered as warnings
// before a given change is rendered.
//
// As with the RenderHuman function, the indent should only be applied on
// multiline warnings and on the second and following lines.
func (diff Diff) WarningsHuman(indent int, opts RenderHumanOpts) []string {
	return diff.Renderer.WarningsHuman(diff, indent, opts)
}

type DiffRenderer interface {
	RenderHuman(diff Diff, indent int, opts RenderHumanOpts) string
	WarningsHuman(diff Diff, indent int, opts RenderHumanOpts) []string
}

// RenderHumanOpts contains options that can control how the human render
// function of the DiffRenderer will function.
type RenderHumanOpts struct {
	Colorize *colorstring.Colorize

	// OverrideNullSuffix tells the Renderer not to display the `-> null` suffix
	// that is normally displayed when an element, attribute, or block is
	// deleted.
	OverrideNullSuffix bool

	// ForceForcesReplacement tells the Renderer to display the
	// `# forces replacement` suffix, even if a diff doesn't have the Replace
	// field set.
	//
	// Some renderers (like the Set renderer) don't display the suffix
	// themselves but force their child diffs to display it instead.
	ForceForcesReplacement bool

	// ForbidForcesReplacement is the opposite of ForceForcesReplacement. It
	// tells the Renderer to not display the '# forces replacement' suffix, even
	// if a diff does have the Replace field set.
	//
	// Some renderers (like the Unknown renderer) want to capture the
	// forceReplacement setting at their level instead of within the children.
	ForbidForcesReplacement bool

	// ShowUnchangedChildren instructs the Renderer to render all children of a
	// given complex change, instead of hiding unchanged items and compressing
	// them into a single line.
	ShowUnchangedChildren bool

	// HideDiffActionSymbols tells the renderer not to show the '+'/'-' symbols
	// and to skip the places where the symbols would result in an offset.
	HideDiffActionSymbols bool
}

// NewRenderHumanOpts creates a new RenderHumanOpts struct with the required
// fields set.
func NewRenderHumanOpts(colorize *colorstring.Colorize) RenderHumanOpts {
	return RenderHumanOpts{
		Colorize: colorize,
	}
}

// Clone returns a new RenderOpts object, that matches the original but can be
// edited without changing the original.
func (opts RenderHumanOpts) Clone() RenderHumanOpts {
	return RenderHumanOpts{
		Colorize: opts.Colorize,

		OverrideNullSuffix:    opts.OverrideNullSuffix,
		ShowUnchangedChildren: opts.ShowUnchangedChildren,
		HideDiffActionSymbols: opts.HideDiffActionSymbols,

		// ForceForcesReplacement and ForbidForcesReplacement are special cases
		// in that they don't cascade. So each diff should decide independently
		// whether it's direct children should override their internal Replace
		// logic, instead of an ancestor making the switch and affecting the
		// entire tree.
		ForceForcesReplacement:  false,
		ForbidForcesReplacement: false,
	}
}
