package jsonformat

import (
	"fmt"

	"github.com/mitchellh/colorstring"

	"github.com/hashicorp/terraform/internal/command/format"
	"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
	"github.com/hashicorp/terraform/internal/command/jsonformat/differ"
	"github.com/hashicorp/terraform/internal/command/jsonformat/structured"
	"github.com/hashicorp/terraform/internal/command/jsonplan"
	"github.com/hashicorp/terraform/internal/command/jsonprovider"
	"github.com/hashicorp/terraform/internal/command/jsonstate"
	viewsjson "github.com/hashicorp/terraform/internal/command/views/json"
	"github.com/hashicorp/terraform/internal/plans"
	"github.com/hashicorp/terraform/internal/terminal"
	ctyjson "github.com/zclconf/go-cty/cty/json"
)

type JSONLogType string

type JSONLog struct {
	Message    string                 `json:"@message"`
	Type       JSONLogType            `json:"type"`
	Diagnostic *viewsjson.Diagnostic  `json:"diagnostic"`
	Outputs    viewsjson.Outputs      `json:"outputs"`
	Hook       map[string]interface{} `json:"hook"`
}

const (
	LogVersion           JSONLogType = "version"
	LogDiagnostic        JSONLogType = "diagnostic"
	LogPlannedChange     JSONLogType = "planned_change"
	LogRefreshStart      JSONLogType = "refresh_start"
	LogRefreshComplete   JSONLogType = "refresh_complete"
	LogApplyStart        JSONLogType = "apply_start"
	LogApplyErrored      JSONLogType = "apply_errored"
	LogApplyComplete     JSONLogType = "apply_complete"
	LogChangeSummary     JSONLogType = "change_summary"
	LogProvisionStart    JSONLogType = "provision_start"
	LogProvisionProgress JSONLogType = "provision_progress"
	LogProvisionComplete JSONLogType = "provision_complete"
	LogProvisionErrored  JSONLogType = "provision_errored"
	LogOutputs           JSONLogType = "outputs"
)

type Renderer struct {
	Streams  *terminal.Streams
	Colorize *colorstring.Colorize

	RunningInAutomation bool
}

func (renderer Renderer) RenderHumanPlan(plan Plan, mode plans.Mode, opts ...PlanRendererOpt) {
	// TODO(liamcervante): Tidy up this detection of version differences, we
	// should only report warnings when the plan is generated using a newer
	// version then we are executing. We could also look into major vs minor
	// version differences. This should work for alpha testing in the meantime.
	if plan.PlanFormatVersion != jsonplan.FormatVersion || plan.ProviderFormatVersion != jsonprovider.FormatVersion {
		renderer.Streams.Println(format.WordWrap(
			renderer.Colorize.Color("\n[bold][red]Warning:[reset][bold] This plan was generated using a different version of Terraform, the diff presented here may be missing representations of recent features."),
			renderer.Streams.Stdout.Columns()))
	}

	plan.renderHuman(renderer, mode, opts...)
}

func (renderer Renderer) RenderHumanState(state State) {
	// TODO(liamcervante): Tidy up this detection of version differences, we
	// should only report warnings when the plan is generated using a newer
	// version then we are executing. We could also look into major vs minor
	// version differences. This should work for alpha testing in the meantime.
	if state.StateFormatVersion != jsonstate.FormatVersion || state.ProviderFormatVersion != jsonprovider.FormatVersion {
		renderer.Streams.Println(format.WordWrap(
			renderer.Colorize.Color("\n[bold][red]Warning:[reset][bold] This state was retrieved using a different version of Terraform, the state presented here maybe missing representations of recent features."),
			renderer.Streams.Stdout.Columns()))
	}

	if state.Empty() {
		renderer.Streams.Println("The state file is empty. No resources are represented.")
		return
	}

	opts := computed.NewRenderHumanOpts(renderer.Colorize)
	opts.ShowUnchangedChildren = true
	opts.HideDiffActionSymbols = true

	state.renderHumanStateModule(renderer, state.RootModule, opts, true)
	state.renderHumanStateOutputs(renderer, opts)
}

func (r Renderer) RenderLog(log *JSONLog) error {
	switch log.Type {
	case LogRefreshComplete,
		LogVersion,
		LogPlannedChange,
		LogProvisionComplete,
		LogProvisionErrored,
		LogApplyErrored:
		// We won't display these types of logs
		return nil

	case LogApplyStart, LogApplyComplete, LogRefreshStart, LogProvisionStart:
		msg := fmt.Sprintf(r.Colorize.Color("[bold]%s[reset]"), log.Message)
		r.Streams.Println(msg)

	case LogDiagnostic:
		diag := format.DiagnosticFromJSON(log.Diagnostic, r.Colorize, 78)
		r.Streams.Print(diag)

	case LogOutputs:
		if len(log.Outputs) > 0 {
			r.Streams.Println(r.Colorize.Color("[bold][green]Outputs:[reset]"))
			for name, output := range log.Outputs {
				change := structured.FromJsonViewsOutput(output)
				ctype, err := ctyjson.UnmarshalType(output.Type)
				if err != nil {
					return err
				}

				opts := computed.NewRenderHumanOpts(r.Colorize)
				opts.ShowUnchangedChildren = true

				outputDiff := differ.ComputeDiffForType(change, ctype)
				outputStr := outputDiff.RenderHuman(0, opts)

				msg := fmt.Sprintf("%s = %s", name, outputStr)
				r.Streams.Println(msg)
			}
		}

	case LogProvisionProgress:
		provisioner := log.Hook["provisioner"].(string)
		output := log.Hook["output"].(string)
		resource := log.Hook["resource"].(map[string]interface{})
		resourceAddr := resource["addr"].(string)

		msg := fmt.Sprintf(r.Colorize.Color("[bold]%s: (%s):[reset] %s"),
			resourceAddr, provisioner, output)
		r.Streams.Println(msg)

	case LogChangeSummary:
		// Normally, we will only render the apply change summary since the renderer
		// generates a plan change summary for us
		msg := fmt.Sprintf(r.Colorize.Color("[bold][green]%s[reset]"), log.Message)
		r.Streams.Println("\n" + msg + "\n")

	default:
		// If the log type is not a known log type, we will just print the log message
		r.Streams.Println(log.Message)
	}

	return nil
}
