package jsonformat

import (
	"bytes"
	"encoding/json"
	"fmt"
	"sort"
	"strings"

	"github.com/hashicorp/terraform/internal/command/format"
	"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
	"github.com/hashicorp/terraform/internal/command/jsonformat/computed/renderers"
	"github.com/hashicorp/terraform/internal/command/jsonplan"
	"github.com/hashicorp/terraform/internal/command/jsonprovider"
	"github.com/hashicorp/terraform/internal/command/jsonstate"
	"github.com/hashicorp/terraform/internal/plans"
)

type PlanRendererOpt int

const (
	detectedDrift  string = "drift"
	proposedChange string = "change"

	Errored PlanRendererOpt = iota
	CanNotApply
)

type Plan struct {
	PlanFormatVersion  string                     `json:"plan_format_version"`
	OutputChanges      map[string]jsonplan.Change `json:"output_changes"`
	ResourceChanges    []jsonplan.ResourceChange  `json:"resource_changes"`
	ResourceDrift      []jsonplan.ResourceChange  `json:"resource_drift"`
	RelevantAttributes []jsonplan.ResourceAttr    `json:"relevant_attributes"`

	ProviderFormatVersion string                            `json:"provider_format_version"`
	ProviderSchemas       map[string]*jsonprovider.Provider `json:"provider_schemas"`
}

func (plan Plan) getSchema(change jsonplan.ResourceChange) *jsonprovider.Schema {
	switch change.Mode {
	case jsonstate.ManagedResourceMode:
		return plan.ProviderSchemas[change.ProviderName].ResourceSchemas[change.Type]
	case jsonstate.DataResourceMode:
		return plan.ProviderSchemas[change.ProviderName].DataSourceSchemas[change.Type]
	default:
		panic("found unrecognized resource mode: " + change.Mode)
	}
}

func (plan Plan) renderHuman(renderer Renderer, mode plans.Mode, opts ...PlanRendererOpt) {
	checkOpts := func(target PlanRendererOpt) bool {
		for _, opt := range opts {
			if opt == target {
				return true
			}
		}
		return false
	}

	diffs := precomputeDiffs(plan, mode)
	haveRefreshChanges := renderHumanDiffDrift(renderer, diffs, mode)

	willPrintResourceChanges := false
	counts := make(map[plans.Action]int)
	var changes []diff
	for _, diff := range diffs.changes {
		action := jsonplan.UnmarshalActions(diff.change.Change.Actions)
		if action == plans.NoOp && !diff.Moved() {
			// Don't show anything for NoOp changes.
			continue
		}
		if action == plans.Delete && diff.change.Mode != jsonstate.ManagedResourceMode {
			// Don't render anything for deleted data sources.
			continue
		}

		changes = append(changes, diff)

		// Don't count move-only changes
		if action != plans.NoOp {
			willPrintResourceChanges = true
			counts[action]++
		}
	}

	// Precompute the outputs early, so we can make a decision about whether we
	// display the "there are no changes messages".
	outputs := renderHumanDiffOutputs(renderer, diffs.outputs)

	if len(changes) == 0 && len(outputs) == 0 {
		// If we didn't find any changes to report at all then this is a
		// "No changes" plan. How we'll present this depends on whether
		// the plan is "applyable" and, if so, whether it had refresh changes
		// that we already would've presented above.

		if checkOpts(Errored) {
			if haveRefreshChanges {
				renderer.Streams.Print(format.HorizontalRule(renderer.Colorize, renderer.Streams.Stdout.Columns()))
				renderer.Streams.Println()
			}
			renderer.Streams.Print(
				renderer.Colorize.Color("\n[reset][bold][red]Planning failed.[reset][bold] Terraform encountered an error while generating this plan.[reset]\n\n"),
			)
		} else {
			switch mode {
			case plans.RefreshOnlyMode:
				if haveRefreshChanges {
					// We already generated a sufficient prompt about what will
					// happen if applying this change above, so we don't need to
					// say anything more.
					return
				}

				renderer.Streams.Print(renderer.Colorize.Color("\n[reset][bold][green]No changes.[reset][bold] Your infrastructure still matches the configuration.[reset]\n\n"))
				renderer.Streams.Println(format.WordWrap(
					"Terraform has checked that the real remote objects still match the result of your most recent changes, and found no differences.",
					renderer.Streams.Stdout.Columns()))
			case plans.DestroyMode:
				if haveRefreshChanges {
					renderer.Streams.Print(format.HorizontalRule(renderer.Colorize, renderer.Streams.Stdout.Columns()))
					fmt.Fprintln(renderer.Streams.Stdout.File)
				}
				renderer.Streams.Print(renderer.Colorize.Color("\n[reset][bold][green]No changes.[reset][bold] No objects need to be destroyed.[reset]\n\n"))
				renderer.Streams.Println(format.WordWrap(
					"Either you have not created any objects yet or the existing objects were already deleted outside of Terraform.",
					renderer.Streams.Stdout.Columns()))
			default:
				if haveRefreshChanges {
					renderer.Streams.Print(format.HorizontalRule(renderer.Colorize, renderer.Streams.Stdout.Columns()))
					renderer.Streams.Println("")
				}
				renderer.Streams.Print(
					renderer.Colorize.Color("\n[reset][bold][green]No changes.[reset][bold] Your infrastructure matches the configuration.[reset]\n\n"),
				)

				if haveRefreshChanges {
					if !checkOpts(CanNotApply) {
						// In this case, applying this plan will not change any
						// remote objects but _will_ update the state to match what
						// we detected during refresh, so we'll reassure the user
						// about that.
						renderer.Streams.Println(format.WordWrap(
							"Your configuration already matches the changes detected above, so applying this plan will only update the state to include the changes detected above and won't change any real infrastructure.",
							renderer.Streams.Stdout.Columns(),
						))
					} else {
						// In this case we detected changes during refresh but this isn't
						// a planning mode where we consider those to be applyable. The
						// user must re-run in refresh-only mode in order to update the
						// state to match the upstream changes.
						suggestion := "."
						if !renderer.RunningInAutomation {
							// The normal message includes a specific command line to run.
							suggestion = ":\n  terraform apply -refresh-only"
						}
						renderer.Streams.Println(format.WordWrap(
							"Your configuration already matches the changes detected above. If you'd like to update the Terraform state to match, create and apply a refresh-only plan"+suggestion,
							renderer.Streams.Stdout.Columns(),
						))
					}
					return
				}

				// If we get down here then we're just in the simple situation where
				// the plan isn't applyable at all.
				renderer.Streams.Println(format.WordWrap(
					"Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.",
					renderer.Streams.Stdout.Columns(),
				))
			}
		}
	}

	if haveRefreshChanges {
		renderer.Streams.Print(format.HorizontalRule(renderer.Colorize, renderer.Streams.Stdout.Columns()))
		renderer.Streams.Println()
	}

	if willPrintResourceChanges {
		renderer.Streams.Println(format.WordWrap(
			"\nTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:",
			renderer.Streams.Stdout.Columns()))
		if counts[plans.Create] > 0 {
			renderer.Streams.Println(renderer.Colorize.Color(actionDescription(plans.Create)))
		}
		if counts[plans.Update] > 0 {
			renderer.Streams.Println(renderer.Colorize.Color(actionDescription(plans.Update)))
		}
		if counts[plans.Delete] > 0 {
			renderer.Streams.Println(renderer.Colorize.Color(actionDescription(plans.Delete)))
		}
		if counts[plans.DeleteThenCreate] > 0 {
			renderer.Streams.Println(renderer.Colorize.Color(actionDescription(plans.DeleteThenCreate)))
		}
		if counts[plans.CreateThenDelete] > 0 {
			renderer.Streams.Println(renderer.Colorize.Color(actionDescription(plans.CreateThenDelete)))
		}
		if counts[plans.Read] > 0 {
			renderer.Streams.Println(renderer.Colorize.Color(actionDescription(plans.Read)))
		}
	}

	if len(changes) > 0 {
		if checkOpts(Errored) {
			renderer.Streams.Printf("\nTerraform planned the following actions, but then encountered a problem:\n")
		} else {
			renderer.Streams.Printf("\nTerraform will perform the following actions:\n")
		}

		for _, change := range changes {
			diff, render := renderHumanDiff(renderer, change, proposedChange)
			if render {
				fmt.Fprintln(renderer.Streams.Stdout.File)
				renderer.Streams.Println(diff)
			}
		}

		renderer.Streams.Printf(
			renderer.Colorize.Color("\n[bold]Plan:[reset] %d to add, %d to change, %d to destroy.\n"),
			counts[plans.Create]+counts[plans.DeleteThenCreate]+counts[plans.CreateThenDelete],
			counts[plans.Update],
			counts[plans.Delete]+counts[plans.DeleteThenCreate]+counts[plans.CreateThenDelete])
	}

	if len(outputs) > 0 {
		renderer.Streams.Print("\nChanges to Outputs:\n")
		renderer.Streams.Printf("%s\n", outputs)

		if len(counts) == 0 {
			// If we have output changes but not resource changes then we
			// won't have output any indication about the changes at all yet,
			// so we need some extra context about what it would mean to
			// apply a change that _only_ includes output changes.
			renderer.Streams.Println(format.WordWrap(
				"\nYou can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.",
				renderer.Streams.Stdout.Columns()))
		}
	}
}

func renderHumanDiffOutputs(renderer Renderer, outputs map[string]computed.Diff) string {
	var rendered []string

	var keys []string
	escapedKeys := make(map[string]string)
	var escapedKeyMaxLen int
	for key := range outputs {
		escapedKey := renderers.EnsureValidAttributeName(key)
		keys = append(keys, key)
		escapedKeys[key] = escapedKey
		if len(escapedKey) > escapedKeyMaxLen {
			escapedKeyMaxLen = len(escapedKey)
		}
	}
	sort.Strings(keys)

	for _, key := range keys {
		output := outputs[key]
		if output.Action != plans.NoOp {
			rendered = append(rendered, fmt.Sprintf("%s %-*s = %s", renderer.Colorize.Color(format.DiffActionSymbol(output.Action)), escapedKeyMaxLen, escapedKeys[key], output.RenderHuman(0, computed.NewRenderHumanOpts(renderer.Colorize))))
		}
	}
	return strings.Join(rendered, "\n")
}

func renderHumanDiffDrift(renderer Renderer, diffs diffs, mode plans.Mode) bool {
	var drs []diff

	// In refresh-only mode, we show all resources marked as drifted,
	// including those which have moved without other changes. In other plan
	// modes, move-only changes will be rendered in the planned changes, so
	// we skip them here.

	if mode == plans.RefreshOnlyMode {
		drs = diffs.drift
	} else {
		for _, dr := range diffs.drift {
			if dr.diff.Action != plans.NoOp {
				drs = append(drs, dr)
			}
		}
	}

	if len(drs) == 0 {
		return false
	}

	// If the overall plan is empty, and it's not a refresh only plan then we
	// won't show any drift changes.
	if diffs.Empty() && mode != plans.RefreshOnlyMode {
		return false
	}

	renderer.Streams.Print(renderer.Colorize.Color("\n[bold][cyan]Note:[reset][bold] Objects have changed outside of Terraform\n"))
	renderer.Streams.Println()
	renderer.Streams.Print(format.WordWrap(
		"Terraform detected the following changes made outside of Terraform since the last \"terraform apply\" which may have affected this plan:\n",
		renderer.Streams.Stdout.Columns()))

	for _, drift := range drs {
		diff, render := renderHumanDiff(renderer, drift, detectedDrift)
		if render {
			renderer.Streams.Println()
			renderer.Streams.Println(diff)
		}
	}

	switch mode {
	case plans.RefreshOnlyMode:
		renderer.Streams.Println(format.WordWrap(
			"\n\nThis is a refresh-only plan, so Terraform will not take any actions to undo these. If you were expecting these changes then you can apply this plan to record the updated values in the Terraform state without changing any remote objects.",
			renderer.Streams.Stdout.Columns(),
		))
	default:
		renderer.Streams.Println(format.WordWrap(
			"\n\nUnless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes.",
			renderer.Streams.Stdout.Columns(),
		))
	}

	return true
}

func renderHumanDiff(renderer Renderer, diff diff, cause string) (string, bool) {

	// Internally, our computed diffs can't tell the difference between a
	// replace action (eg. CreateThenDestroy, DestroyThenCreate) and a simple
	// update action. So, at the top most level we rely on the action provided
	// by the plan itself instead of what we compute. Nested attributes and
	// blocks however don't have the replace type of actions, so we can trust
	// the computed actions of these.

	action := jsonplan.UnmarshalActions(diff.change.Change.Actions)
	if action == plans.NoOp && (len(diff.change.PreviousAddress) == 0 || diff.change.PreviousAddress == diff.change.Address) {
		// Skip resource changes that have nothing interesting to say.
		return "", false
	}

	var buf bytes.Buffer
	buf.WriteString(renderer.Colorize.Color(resourceChangeComment(diff.change, action, cause)))
	buf.WriteString(fmt.Sprintf("%s %s %s", renderer.Colorize.Color(format.DiffActionSymbol(action)), resourceChangeHeader(diff.change), diff.diff.RenderHuman(0, computed.NewRenderHumanOpts(renderer.Colorize))))
	return buf.String(), true
}

func resourceChangeComment(resource jsonplan.ResourceChange, action plans.Action, changeCause string) string {
	var buf bytes.Buffer

	dispAddr := resource.Address
	if len(resource.Deposed) != 0 {
		dispAddr = fmt.Sprintf("%s (deposed object %s)", dispAddr, resource.Deposed)
	}

	switch action {
	case plans.Create:
		buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] will be created", dispAddr))
	case plans.Read:
		buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] will be read during apply", dispAddr))
		switch resource.ActionReason {
		case jsonplan.ResourceInstanceReadBecauseConfigUnknown:
			buf.WriteString("\n  # (config refers to values not yet known)")
		case jsonplan.ResourceInstanceReadBecauseDependencyPending:
			buf.WriteString("\n  # (depends on a resource or a module with changes pending)")
		}
	case plans.Update:
		switch changeCause {
		case proposedChange:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] will be updated in-place", dispAddr))
		case detectedDrift:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] has changed", dispAddr))
		default:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] update (unknown reason %s)", dispAddr, changeCause))
		}
	case plans.CreateThenDelete, plans.DeleteThenCreate:
		switch resource.ActionReason {
		case jsonplan.ResourceInstanceReplaceBecauseTainted:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] is tainted, so must be [bold][red]replaced[reset]", dispAddr))
		case jsonplan.ResourceInstanceReplaceByRequest:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] will be [bold][red]replaced[reset], as requested", dispAddr))
		case jsonplan.ResourceInstanceReplaceByTriggers:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] will be [bold][red]replaced[reset] due to changes in replace_triggered_by", dispAddr))
		default:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] must be [bold][red]replaced[reset]", dispAddr))
		}
	case plans.Delete:
		switch changeCause {
		case proposedChange:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] will be [bold][red]destroyed[reset]", dispAddr))
		case detectedDrift:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] has been deleted", dispAddr))
		default:
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] delete (unknown reason %s)", dispAddr, changeCause))
		}
		// 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 resource.ActionReason {
		case jsonplan.ResourceInstanceDeleteBecauseNoResourceConfig:
			buf.WriteString(fmt.Sprintf("\n  # (because %s.%s is not in configuration)", resource.Type, resource.Name))
		case jsonplan.ResourceInstanceDeleteBecauseNoMoveTarget:
			buf.WriteString(fmt.Sprintf("\n  # (because %s was moved to %s, which is not in configuration)", resource.PreviousAddress, resource.Address))
		case jsonplan.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)", resource.ModuleAddress))
		case jsonplan.ResourceInstanceDeleteBecauseWrongRepetition:
			var index interface{}
			if resource.Index != nil {
				if err := json.Unmarshal(resource.Index, &index); err != nil {
					panic(err)
				}
			}

			// We have some different variations of this one
			switch index.(type) {
			case nil:
				buf.WriteString("\n  # (because resource uses count or for_each)")
			case float64:
				buf.WriteString("\n  # (because resource does not use count)")
			case string:
				buf.WriteString("\n  # (because resource does not use for_each)")
			}
		case jsonplan.ResourceInstanceDeleteBecauseCountIndex:
			buf.WriteString(fmt.Sprintf("\n  # (because index [%s] is out of range for count)", resource.Index))
		case jsonplan.ResourceInstanceDeleteBecauseEachKey:
			buf.WriteString(fmt.Sprintf("\n  # (because key [%s] is not in for_each map)", resource.Index))
		}
		if len(resource.Deposed) != 0 {
			// Some extra context about this unusual situation.
			buf.WriteString("\n  # (left over from a partially-failed replacement of this instance)")
		}
	case plans.NoOp:
		if len(resource.PreviousAddress) > 0 && resource.PreviousAddress != resource.Address {
			buf.WriteString(fmt.Sprintf("[bold]  # %s[reset] has moved to [bold]%s[reset]", resource.PreviousAddress, 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("\n")

	if len(resource.PreviousAddress) > 0 && resource.PreviousAddress != resource.Address && action != plans.NoOp {
		buf.WriteString(fmt.Sprintf("  # [reset](moved from %s)\n", resource.PreviousAddress))
	}

	return buf.String()
}

func resourceChangeHeader(change jsonplan.ResourceChange) string {
	mode := "resource"
	if change.Mode != jsonstate.ManagedResourceMode {
		mode = "data"
	}
	return fmt.Sprintf("%s \"%s\" \"%s\"", mode, change.Type, change.Name)
}

func actionDescription(action plans.Action) string {
	switch action {
	case plans.Create:
		return "  [green]+[reset] create"
	case plans.Delete:
		return "  [red]-[reset] destroy"
	case plans.Update:
		return "  [yellow]~[reset] update in-place"
	case plans.CreateThenDelete:
		return "[green]+[reset]/[red]-[reset] create replacement and then destroy"
	case plans.DeleteThenCreate:
		return "[red]-[reset]/[green]+[reset] destroy and then create replacement"
	case plans.Read:
		return " [cyan]<=[reset] read (data resources)"
	default:
		panic(fmt.Sprintf("unrecognized change type: %s", action.String()))
	}
}
