package renderers

import (
	"bytes"
	"fmt"

	"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
	"github.com/hashicorp/terraform/internal/plans"
)

var _ computed.DiffRenderer = (*listRenderer)(nil)

func List(elements []computed.Diff) computed.DiffRenderer {
	return &listRenderer{
		displayContext: true,
		elements:       elements,
	}
}

func NestedList(elements []computed.Diff) computed.DiffRenderer {
	return &listRenderer{
		elements: elements,
	}
}

type listRenderer struct {
	NoWarningsRenderer

	displayContext bool
	elements       []computed.Diff
}

func (renderer listRenderer) RenderHuman(diff computed.Diff, indent int, opts computed.RenderHumanOpts) string {
	if len(renderer.elements) == 0 {
		return fmt.Sprintf("[]%s%s", nullSuffix(diff.Action, opts), forcesReplacement(diff.Replace, opts))
	}

	elementOpts := opts.Clone()
	elementOpts.OverrideNullSuffix = true

	unchangedElementOpts := opts.Clone()
	unchangedElementOpts.ShowUnchangedChildren = true

	var unchangedElements []computed.Diff

	// renderNext tells the renderer to print out the next element in the list
	// whatever state it is in. So, even if a change is a NoOp we will still
	// print it out if the last change we processed wants us to.
	renderNext := false

	var buf bytes.Buffer
	buf.WriteString(fmt.Sprintf("[%s\n", forcesReplacement(diff.Replace, opts)))
	for _, element := range renderer.elements {
		if element.Action == plans.NoOp && !renderNext && !opts.ShowUnchangedChildren {
			unchangedElements = append(unchangedElements, element)
			continue
		}
		renderNext = false

		opts := elementOpts

		// If we want to display the context around this change, we want to
		// render the change immediately before this change in the list, and the
		// change immediately after in the list, even if both these changes are
		// NoOps. This will give the user reading the diff some context as to
		// where in the list these changes are being made, as order matters.
		if renderer.displayContext {
			// If our list of unchanged elements contains more than one entry
			// we'll print out a count of the number of unchanged elements that
			// we skipped. Note, this is the length of the unchanged elements
			// minus 1 as the most recent unchanged element will be printed out
			// in full.
			if len(unchangedElements) > 1 {
				buf.WriteString(fmt.Sprintf("%s%s%s\n", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), unchanged("element", len(unchangedElements)-1, opts)))
			}
			// If our list of unchanged elements contains at least one entry,
			// we're going to print out the most recent change in full. That's
			// what happens here.
			if len(unchangedElements) > 0 {
				lastElement := unchangedElements[len(unchangedElements)-1]
				buf.WriteString(fmt.Sprintf("%s%s%s,\n", formatIndent(indent+1), writeDiffActionSymbol(lastElement.Action, unchangedElementOpts), lastElement.RenderHuman(indent+1, unchangedElementOpts)))
			}
			// We now reset the unchanged elements list, we've printed out a
			// count of all the elements we skipped so we start counting from
			// scratch again. This means that if we process a run of changed
			// elements, they won't all start printing out summaries of every
			// change that happened previously.
			unchangedElements = nil

			if element.Action == plans.NoOp {
				// If this is a NoOp action then we're going to render it below
				// so we need to just override the opts we're going to use to
				// make sure we use the unchanged opts.
				opts = unchangedElementOpts
			} else {
				// As we also want to render the element immediately after any
				// changes, we make a note here to say we should render the next
				// change whatever it is. But, we only want to render the next
				// change if the current change isn't a NoOp. If the current change
				// is a NoOp then it was told to print by the last change and we
				// don't want to cascade and print all changes from now on.
				renderNext = true
			}
		}

		for _, warning := range element.WarningsHuman(indent+1, opts) {
			buf.WriteString(fmt.Sprintf("%s%s\n", formatIndent(indent+1), warning))
		}
		buf.WriteString(fmt.Sprintf("%s%s%s,\n", formatIndent(indent+1), writeDiffActionSymbol(element.Action, opts), element.RenderHuman(indent+1, opts)))
	}

	// If we were not displaying any context alongside our changes then the
	// unchangedElements list will contain every unchanged element, and we'll
	// print that out as we do with every other collection.
	//
	// If we were displaying context, then this will contain any unchanged
	// elements since our last change, so we should also print it out.
	if len(unchangedElements) > 0 {
		buf.WriteString(fmt.Sprintf("%s%s%s\n", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), unchanged("element", len(unchangedElements), opts)))
	}

	buf.WriteString(fmt.Sprintf("%s%s]%s", formatIndent(indent), writeDiffActionSymbol(plans.NoOp, opts), nullSuffix(diff.Action, opts)))
	return buf.String()
}
