package jsonformat

import (
	"sort"

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

	"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/jsonprovider"
	"github.com/hashicorp/terraform/internal/command/jsonstate"
)

type State struct {
	StateFormatVersion string                      `json:"state_format_version"`
	RootModule         jsonstate.Module            `json:"root"`
	RootModuleOutputs  map[string]jsonstate.Output `json:"root_module_outputs"`

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

func (state State) Empty() bool {
	return len(state.RootModuleOutputs) == 0 && len(state.RootModule.Resources) == 0 && len(state.RootModule.ChildModules) == 0
}

func (state State) GetSchema(resource jsonstate.Resource) *jsonprovider.Schema {
	switch resource.Mode {
	case jsonstate.ManagedResourceMode:
		return state.ProviderSchemas[resource.ProviderName].ResourceSchemas[resource.Type]
	case jsonstate.DataResourceMode:
		return state.ProviderSchemas[resource.ProviderName].DataSourceSchemas[resource.Type]
	default:
		panic("found unrecognized resource mode: " + resource.Mode)
	}
}

func (state State) renderHumanStateModule(renderer Renderer, module jsonstate.Module, opts computed.RenderHumanOpts, first bool) {
	if len(module.Resources) > 0 && !first {
		renderer.Streams.Println()
	}

	for _, resource := range module.Resources {

		if !first {
			renderer.Streams.Println()
		}

		if first {
			first = false
		}

		if len(resource.DeposedKey) > 0 {
			renderer.Streams.Printf("# %s: (deposed object %s)", resource.Address, resource.DeposedKey)
		} else if resource.Tainted {
			renderer.Streams.Printf("# %s: (tainted)", resource.Address)
		} else {
			renderer.Streams.Printf("# %s:", resource.Address)
		}

		renderer.Streams.Println()

		schema := state.GetSchema(resource)
		switch resource.Mode {
		case jsonstate.ManagedResourceMode:
			change := structured.FromJsonResource(resource)
			renderer.Streams.Printf("resource %q %q %s", resource.Type, resource.Name, differ.ComputeDiffForBlock(change, schema.Block).RenderHuman(0, opts))
		case jsonstate.DataResourceMode:
			change := structured.FromJsonResource(resource)
			renderer.Streams.Printf("data %q %q %s", resource.Type, resource.Name, differ.ComputeDiffForBlock(change, schema.Block).RenderHuman(0, opts))
		default:
			panic("found unrecognized resource mode: " + resource.Mode)
		}

		renderer.Streams.Println()
	}

	for _, child := range module.ChildModules {
		state.renderHumanStateModule(renderer, child, opts, first)
	}
}

func (state State) renderHumanStateOutputs(renderer Renderer, opts computed.RenderHumanOpts) {

	if len(state.RootModuleOutputs) > 0 {
		renderer.Streams.Printf("\n\nOutputs:\n\n")

		var keys []string
		for key := range state.RootModuleOutputs {
			keys = append(keys, key)
		}
		sort.Strings(keys)

		for _, key := range keys {
			output := state.RootModuleOutputs[key]
			change := structured.FromJsonOutput(output)
			ctype, err := ctyjson.UnmarshalType(output.Type)
			if err != nil {
				// We can actually do this without the type, so even if we fail
				// to work out the type let's just render this anyway.
				renderer.Streams.Printf("%s = %s\n", key, differ.ComputeDiffForOutput(change).RenderHuman(0, opts))
			} else {
				renderer.Streams.Printf("%s = %s\n", key, differ.ComputeDiffForType(change, ctype).RenderHuman(0, opts))
			}
		}
	}
}
