// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package renderers

import (
	"fmt"
	"math/big"
	"strings"

	"github.com/zclconf/go-cty/cty"

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

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

func Primitive(before, after interface{}, ctype cty.Type) computed.DiffRenderer {
	return &primitiveRenderer{
		before: before,
		after:  after,
		ctype:  ctype,
	}
}

type primitiveRenderer struct {
	NoWarningsRenderer

	before interface{}
	after  interface{}
	ctype  cty.Type
}

func (renderer primitiveRenderer) RenderHuman(diff computed.Diff, indent int, opts computed.RenderHumanOpts) string {
	if renderer.ctype == cty.String {
		return renderer.renderStringDiff(diff, indent, opts)
	}

	beforeValue := renderPrimitiveValue(renderer.before, renderer.ctype, opts)
	afterValue := renderPrimitiveValue(renderer.after, renderer.ctype, opts)

	switch diff.Action {
	case plans.Create:
		return fmt.Sprintf("%s%s", afterValue, forcesReplacement(diff.Replace, opts))
	case plans.Delete:
		return fmt.Sprintf("%s%s%s", beforeValue, nullSuffix(diff.Action, opts), forcesReplacement(diff.Replace, opts))
	case plans.NoOp:
		return fmt.Sprintf("%s%s", beforeValue, forcesReplacement(diff.Replace, opts))
	default:
		return fmt.Sprintf("%s %s %s%s", beforeValue, opts.Colorize.Color("[yellow]->[reset]"), afterValue, forcesReplacement(diff.Replace, opts))
	}
}

func renderPrimitiveValue(value interface{}, t cty.Type, opts computed.RenderHumanOpts) string {
	if value == nil {
		return opts.Colorize.Color("[dark_gray]null[reset]")
	}

	switch {
	case t == cty.Bool:
		if value.(bool) {
			return "true"
		}
		return "false"
	case t == cty.Number:
		bf := big.NewFloat(value.(float64))
		return bf.Text('f', -1)
	default:
		panic("unrecognized primitive type: " + t.FriendlyName())
	}
}

func (renderer primitiveRenderer) renderStringDiff(diff computed.Diff, indent int, opts computed.RenderHumanOpts) string {

	// We process multiline strings at the end of the switch statement.
	var lines []string

	switch diff.Action {
	case plans.Create, plans.NoOp:
		str := evaluatePrimitiveString(renderer.after, opts)

		if str.Json != nil {
			if diff.Action == plans.NoOp {
				return renderer.renderStringDiffAsJson(diff, indent, opts, str, str)
			} else {
				return renderer.renderStringDiffAsJson(diff, indent, opts, evaluatedString{}, str)
			}
		}

		if !str.IsMultiline {
			return fmt.Sprintf("%s%s", str.RenderSimple(), forcesReplacement(diff.Replace, opts))
		}

		// We are creating a single multiline string, so let's split by the new
		// line character. While we are doing this, we are going to insert our
		// indents and make sure each line is formatted correctly.
		lines = strings.Split(strings.ReplaceAll(str.String, "\n", fmt.Sprintf("\n%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts))), "\n")

		// We now just need to do the same for the first entry in lines, because
		// we split on the new line characters which won't have been at the
		// beginning of the first line.
		lines[0] = fmt.Sprintf("%s%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), lines[0])
	case plans.Delete:
		str := evaluatePrimitiveString(renderer.before, opts)
		if str.IsNull {
			// We don't put the null suffix (-> null) here because the final
			// render or null -> null would look silly.
			return fmt.Sprintf("%s%s", str.RenderSimple(), forcesReplacement(diff.Replace, opts))
		}

		if str.Json != nil {
			return renderer.renderStringDiffAsJson(diff, indent, opts, str, evaluatedString{})
		}

		if !str.IsMultiline {
			return fmt.Sprintf("%s%s%s", str.RenderSimple(), nullSuffix(diff.Action, opts), forcesReplacement(diff.Replace, opts))
		}

		// We are creating a single multiline string, so let's split by the new
		// line character. While we are doing this, we are going to insert our
		// indents and make sure each line is formatted correctly.
		lines = strings.Split(strings.ReplaceAll(str.String, "\n", fmt.Sprintf("\n%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts))), "\n")

		// We now just need to do the same for the first entry in lines, because
		// we split on the new line characters which won't have been at the
		// beginning of the first line.
		lines[0] = fmt.Sprintf("%s%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), lines[0])
	default:
		beforeString := evaluatePrimitiveString(renderer.before, opts)
		afterString := evaluatePrimitiveString(renderer.after, opts)

		if beforeString.Json != nil && afterString.Json != nil {
			return renderer.renderStringDiffAsJson(diff, indent, opts, beforeString, afterString)
		}

		if beforeString.Json != nil || afterString.Json != nil {
			// This means one of the strings is JSON and one isn't. We're going
			// to be a little inefficient here, but we can just reuse another
			// renderer for this so let's keep it simple.
			return computed.NewDiff(
				TypeChange(
					computed.NewDiff(Primitive(renderer.before, nil, cty.String), plans.Delete, false),
					computed.NewDiff(Primitive(nil, renderer.after, cty.String), plans.Create, false)),
				diff.Action,
				diff.Replace).RenderHuman(indent, opts)
		}

		if !beforeString.IsMultiline && !afterString.IsMultiline {
			return fmt.Sprintf("%s %s %s%s", beforeString.RenderSimple(), opts.Colorize.Color("[yellow]->[reset]"), afterString.RenderSimple(), forcesReplacement(diff.Replace, opts))
		}

		beforeLines := strings.Split(beforeString.String, "\n")
		afterLines := strings.Split(afterString.String, "\n")

		processIndices := func(beforeIx, afterIx int) {
			if beforeIx < 0 || beforeIx >= len(beforeLines) {
				lines = append(lines, fmt.Sprintf("%s%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.Create, opts), afterLines[afterIx]))
				return
			}

			if afterIx < 0 || afterIx >= len(afterLines) {
				lines = append(lines, fmt.Sprintf("%s%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.Delete, opts), beforeLines[beforeIx]))
				return
			}

			lines = append(lines, fmt.Sprintf("%s%s%s", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), beforeLines[beforeIx]))
		}
		isObjType := func(_ string) bool {
			return false
		}

		collections.ProcessSlice(beforeLines, afterLines, processIndices, isObjType)
	}

	// We return early if we find non-multiline strings or JSON strings, so we
	// know here that we just render the lines slice properly.
	return fmt.Sprintf("<<-EOT%s\n%s\n%s%sEOT%s",
		forcesReplacement(diff.Replace, opts),
		strings.Join(lines, "\n"),
		formatIndent(indent),
		writeDiffActionSymbol(plans.NoOp, opts),
		nullSuffix(diff.Action, opts))
}

func (renderer primitiveRenderer) renderStringDiffAsJson(diff computed.Diff, indent int, opts computed.RenderHumanOpts, before evaluatedString, after evaluatedString) string {
	jsonDiff := RendererJsonOpts().Transform(structured.Change{
		BeforeExplicit:     diff.Action != plans.Create,
		AfterExplicit:      diff.Action != plans.Delete,
		Before:             before.Json,
		After:              after.Json,
		Unknown:            false,
		BeforeSensitive:    false,
		AfterSensitive:     false,
		ReplacePaths:       attribute_path.Empty(false),
		RelevantAttributes: attribute_path.AlwaysMatcher(),
	})

	action := diff.Action

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

	var whitespace, replace string
	if jsonDiff.Action == plans.NoOp && diff.Action == plans.Update {
		// Then this means we are rendering a whitespace only change. The JSON
		// differ will have ignored the whitespace changes so that makes the
		// diff we are about to print out very confusing without extra
		// explanation.
		if diff.Replace {
			whitespace = " # whitespace changes force replacement"
		} else {
			whitespace = " # whitespace changes"
		}

		// Because we'd be showing no changes otherwise:
		jsonOpts.ShowUnchangedChildren = true

		// Whitespace changes should not appear as if edited.
		action = plans.NoOp
	} else {
		// We only show the replace suffix if we didn't print something out
		// about whitespace changes.
		replace = forcesReplacement(diff.Replace, opts)
	}

	renderedJsonDiff := jsonDiff.RenderHuman(indent+1, jsonOpts)

	if diff.Action == plans.Create || diff.Action == plans.Delete {
		// We don't display the '+' or '-' symbols on the JSON diffs, we should
		// still display the '~' for an update action though.
		action = plans.NoOp
	}

	if strings.Contains(renderedJsonDiff, "\n") {
		return fmt.Sprintf("jsonencode(%s\n%s%s%s%s\n%s%s)%s", whitespace, formatIndent(indent+1), writeDiffActionSymbol(action, opts), renderedJsonDiff, replace, formatIndent(indent), writeDiffActionSymbol(plans.NoOp, opts), nullSuffix(diff.Action, opts))
	}
	return fmt.Sprintf("jsonencode(%s)%s%s", renderedJsonDiff, whitespace, replace)
}
