package jsonchecks

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

	"github.com/hashicorp/terraform/internal/states"
)

// MarshalCheckStates is the main entry-point for this package, which takes
// the top-level model object for checks in state and plan, and returns a
// JSON representation of it suitable for use in public integration points.
func MarshalCheckStates(results *states.CheckResults) []byte {
	jsonResults := make([]checkResultStatic, 0, results.ConfigResults.Len())

	for _, elem := range results.ConfigResults.Elems {
		staticAddr := elem.Key
		aggrResult := elem.Value

		objects := make([]checkResultDynamic, 0, aggrResult.ObjectResults.Len())
		for _, elem := range aggrResult.ObjectResults.Elems {
			dynamicAddr := elem.Key
			result := elem.Value

			problems := make([]checkProblem, 0, len(result.FailureMessages))
			for _, msg := range result.FailureMessages {
				problems = append(problems, checkProblem{
					Message: msg,
				})
			}
			sort.Slice(problems, func(i, j int) bool {
				return problems[i].Message < problems[j].Message
			})

			objects = append(objects, checkResultDynamic{
				Address:  makeDynamicObjectAddr(dynamicAddr),
				Status:   checkStatusForJSON(result.Status),
				Problems: problems,
			})
		}

		sort.Slice(objects, func(i, j int) bool {
			return objects[i].Address["to_display"].(string) < objects[j].Address["to_display"].(string)
		})

		jsonResults = append(jsonResults, checkResultStatic{
			Address:   makeStaticObjectAddr(staticAddr),
			Status:    checkStatusForJSON(aggrResult.Status),
			Instances: objects,
		})
	}

	sort.Slice(jsonResults, func(i, j int) bool {
		return jsonResults[i].Address["to_display"].(string) < jsonResults[j].Address["to_display"].(string)
	})

	ret, err := json.Marshal(jsonResults)
	if err != nil {
		// We totally control the input to json.Marshal, so any error here
		// is a bug in the code above.
		panic(fmt.Sprintf("invalid input to json.Marshal: %s", err))
	}
	return ret
}

// checkResultStatic is the container for the static, configuration-driven
// idea of "checkable object" -- a resource block with conditions, for example --
// which ensures that we can always say _something_ about each checkable
// object in the configuration even if Terraform Core encountered an error
// before being able to determine the dynamic instances of the checkable object.
type checkResultStatic struct {
	ExperimentalNote experimentalNote `json:"//"`

	// Address is the address of the checkable object this result relates to.
	Address staticObjectAddr `json:"address"`

	// Status is the aggregate status for all of the dynamic objects belonging
	// to this static object.
	Status checkStatus `json:"status"`

	// Instances contains the results for each individual dynamic object that
	// belongs to this static object.
	Instances []checkResultDynamic `json:"instances,omitempty"`
}

// checkResultDynamic describes the check result for a dynamic object, which
// results from Terraform Core evaluating the "expansion" (e.g. count or for_each)
// of the containing object or its own containing module(s).
type checkResultDynamic struct {
	// Address augments the Address of the containing checkResultStatic with
	// instance-specific extra properties or overridden properties.
	Address dynamicObjectAddr `json:"address"`

	// Status is the status for this specific dynamic object.
	Status checkStatus `json:"status"`

	// Problems describes some optional details associated with a failure
	// status, describing what fails.
	//
	// This does not include the errors for status "error", because Terraform
	// Core emits those separately as normal diagnostics. However, if a
	// particular object has a mixture of conditions that failed and conditions
	// that were invalid then status can be "error" while simultaneously
	// returning problems in this property.
	Problems []checkProblem `json:"problems,omitempty"`
}

// checkProblem describes one of potentially several problems that led to
// a check being classified as status "fail".
type checkProblem struct {
	// Message is the condition error message provided by the author.
	Message string `json:"message"`

	// We don't currently have any other problem-related data, but this is
	// intentionally an object to allow us to add other data over time, such
	// as the source location where the failing condition was defined.
}

type experimentalNote struct{}

func (n experimentalNote) MarshalJSON() ([]byte, error) {
	return []byte(`"EXPERIMENTAL: see docs for details"`), nil
}
