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

package tfjson

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"

	"github.com/hashicorp/go-version"
)

// PlanFormatVersionConstraints defines the versions of the JSON plan format
// that are supported by this package.
var PlanFormatVersionConstraints = ">= 0.1, < 2.0"

// ResourceMode is a string representation of the resource type found
// in certain fields in the plan.
type ResourceMode string

const (
	// DataResourceMode is the resource mode for data sources.
	DataResourceMode ResourceMode = "data"

	// ManagedResourceMode is the resource mode for managed resources.
	ManagedResourceMode ResourceMode = "managed"
)

// Plan represents the entire contents of an output Terraform plan.
type Plan struct {
	// useJSONNumber opts into the behavior of calling
	// json.Decoder.UseNumber prior to decoding the plan, which turns
	// numbers into json.Numbers instead of float64s. Set it using
	// Plan.UseJSONNumber.
	useJSONNumber bool

	// The version of the plan format. This should always match the
	// PlanFormatVersion constant in this package, or else an unmarshal
	// will be unstable.
	FormatVersion string `json:"format_version,omitempty"`

	// The version of Terraform used to make the plan.
	TerraformVersion string `json:"terraform_version,omitempty"`

	// The variables set in the root module when creating the plan.
	Variables map[string]*PlanVariable `json:"variables,omitempty"`

	// The common state representation of resources within this plan.
	// This is a product of the existing state merged with the diff for
	// this plan.
	PlannedValues *StateValues `json:"planned_values,omitempty"`

	// The change operations for resources and data sources within this plan
	// resulting from resource drift.
	ResourceDrift []*ResourceChange `json:"resource_drift,omitempty"`

	// The change operations for resources and data sources within this
	// plan.
	ResourceChanges []*ResourceChange `json:"resource_changes,omitempty"`

	// DeferredChanges contains the change operations for resources that are deferred
	// for this plan.
	DeferredChanges []*DeferredResourceChange `json:"deferred_changes,omitempty"`

	// Complete indicates that all resources have successfully planned changes.
	// This will be false if there are DeferredChanges or if the -target flag is used.
	//
	// Complete was introduced in Terraform 1.8 and will be nil for all previous
	// Terraform versions.
	Complete *bool `json:"complete,omitempty"`

	// The change operations for outputs within this plan.
	OutputChanges map[string]*Change `json:"output_changes,omitempty"`

	// The Terraform state prior to the plan operation. This is the
	// same format as PlannedValues, without the current diff merged.
	PriorState *State `json:"prior_state,omitempty"`

	// The Terraform configuration used to make the plan.
	Config *Config `json:"configuration,omitempty"`

	// RelevantAttributes represents any resource instances and their
	// attributes which may have contributed to the planned changes
	RelevantAttributes []ResourceAttribute `json:"relevant_attributes,omitempty"`

	// Checks contains the results of any conditional checks executed, or
	// planned to be executed, during this plan.
	Checks []CheckResultStatic `json:"checks,omitempty"`

	// Timestamp contains the static timestamp that Terraform considers to be
	// the time this plan executed, in UTC.
	Timestamp string `json:"timestamp,omitempty"`

	ActionInvocations []*ActionInvocation `json:"action_invocations,omitempty"`
}

// ResourceAttribute describes a full path to a resource attribute
type ResourceAttribute struct {
	// Resource describes resource instance address (e.g. null_resource.foo)
	Resource string `json:"resource"`
	// Attribute describes the attribute path using a lossy representation
	// of cty.Path. (e.g. ["id"] or ["objects", 0, "val"]).
	Attribute []json.RawMessage `json:"attribute"`
}

// UseJSONNumber controls whether the Plan will be decoded using the
// json.Number behavior or the float64 behavior. When b is true, the Plan will
// represent numbers in PlanOutputs as json.Numbers. When b is false, the
// Plan will represent numbers in PlanOutputs as float64s.
func (p *Plan) UseJSONNumber(b bool) {
	p.useJSONNumber = b
}

// Validate checks to ensure that the plan is present, and the
// version matches the version supported by this library.
func (p *Plan) Validate() error {
	if p == nil {
		return errors.New("plan is nil")
	}

	if p.FormatVersion == "" {
		return errors.New("unexpected plan input, format version is missing")
	}

	constraint, err := version.NewConstraint(PlanFormatVersionConstraints)
	if err != nil {
		return fmt.Errorf("invalid version constraint: %w", err)
	}

	version, err := version.NewVersion(p.FormatVersion)
	if err != nil {
		return fmt.Errorf("invalid format version %q: %w", p.FormatVersion, err)
	}

	if !constraint.Check(version) {
		return fmt.Errorf("unsupported plan format version: %q does not satisfy %q",
			version, constraint)
	}

	return nil
}

func (p *Plan) UnmarshalJSON(b []byte) error {
	type rawPlan Plan
	var plan rawPlan

	dec := json.NewDecoder(bytes.NewReader(b))
	if p.useJSONNumber {
		dec.UseNumber()
	}
	err := dec.Decode(&plan)
	if err != nil {
		return err
	}

	*p = *(*Plan)(&plan)

	return p.Validate()
}

// ResourceChange is a description of an individual change action
// that Terraform plans to use to move from the prior state to a new
// state matching the configuration.
type ResourceChange struct {
	// The absolute resource address.
	Address string `json:"address,omitempty"`

	// The absolute address that this resource instance had
	// at the conclusion of a previous plan.
	PreviousAddress string `json:"previous_address,omitempty"`

	// The module portion of the above address. Omitted if the instance
	// is in the root module.
	ModuleAddress string `json:"module_address,omitempty"`

	// The resource mode.
	Mode ResourceMode `json:"mode,omitempty"`

	// The resource type, example: "aws_instance" for aws_instance.foo.
	Type string `json:"type,omitempty"`

	// The resource name, example: "foo" for aws_instance.foo.
	Name string `json:"name,omitempty"`

	// The instance key for any resources that have been created using
	// "count" or "for_each". If neither of these apply the key will be
	// empty.
	//
	// This value can be either an integer (int) or a string.
	Index interface{} `json:"index,omitempty"`

	// The name of the provider this resource belongs to. This allows
	// the provider to be interpreted unambiguously in the unusual
	// situation where a provider offers a resource type whose name
	// does not start with its own name, such as the "googlebeta"
	// provider offering "google_compute_instance".
	ProviderName string `json:"provider_name,omitempty"`

	// An identifier used during replacement operations, and can be
	// used to identify the exact resource being replaced in state.
	DeposedKey string `json:"deposed,omitempty"`

	// The data describing the change that will be made to this object.
	Change *Change `json:"change,omitempty"`
}

// Change is the representation of a proposed change for an object.
type Change struct {
	// The action to be carried out by this change.
	Actions Actions `json:"actions,omitempty"`

	// Before and After are representations of the object value both
	// before and after the action. For create and delete actions,
	// either Before or After is unset (respectively). For no-op
	// actions, both values will be identical. After will be incomplete
	// if there are values within it that won't be known until after
	// apply.
	Before interface{} `json:"before,"`
	After  interface{} `json:"after,omitempty"`

	// A deep object of booleans that denotes any values that are
	// unknown in a resource. These values were previously referred to
	// as "computed" values.
	//
	// If the value cannot be found in this map, then its value should
	// be available within After, so long as the operation supports it.
	AfterUnknown interface{} `json:"after_unknown,omitempty"`

	// BeforeSensitive and AfterSensitive are object values with similar
	// structure to Before and After, but with all sensitive leaf values
	// replaced with true, and all non-sensitive leaf values omitted. These
	// objects should be combined with Before and After to prevent accidental
	// display of sensitive values in user interfaces.
	BeforeSensitive interface{} `json:"before_sensitive,omitempty"`
	AfterSensitive  interface{} `json:"after_sensitive,omitempty"`

	// Importing contains the import metadata about this operation. If importing
	// is present (ie. not null) then the change is an import operation in
	// addition to anything mentioned in the actions field. The actual contents
	// of the Importing struct is subject to change, so downstream consumers
	// should treat any values in here as strictly optional.
	Importing *Importing `json:"importing,omitempty"`

	// GeneratedConfig contains any HCL config generated for this resource
	// during planning as a string.
	//
	// If this is populated, then Importing should also be populated but this
	// might change in the future. However, not all Importing changes will
	// contain generated config.
	GeneratedConfig string `json:"generated_config,omitempty"`

	// ReplacePaths contains a set of paths that point to attributes/elements
	// that are causing the overall resource to be replaced rather than simply
	// updated.
	//
	// This field is always a slice of indexes, where an index in this context
	// is either an integer pointing to a child of a set/list, or a string
	// pointing to the child of a map, object, or block.
	ReplacePaths []interface{} `json:"replace_paths,omitempty"`

	// BeforeIdentity and AfterIdentity are representations of the resource
	// identity value both before and after the action.
	BeforeIdentity interface{} `json:"before_identity,omitempty"`
	AfterIdentity  interface{} `json:"after_identity,omitempty"`
}

// Importing is a nested object for the resource import metadata.
type Importing struct {
	// The original ID of this resource used to target it as part of planned
	// import operation.
	ID string `json:"id,omitempty"`

	// Unknown indicates the ID or identity was unknown at the time of
	// planning. This would have led to the overall change being deferred, as
	// such this should only be true when processing changes from the deferred
	// changes list.
	Unknown bool `json:"unknown,omitempty"`

	// The identity can be used instead of the ID to target the resource as part
	// of the planned import operation.
	Identity interface{} `json:"identity,omitempty"`
}

// PlanVariable is a top-level variable in the Terraform plan.
type PlanVariable struct {
	// The value for this variable at plan time.
	Value interface{} `json:"value,omitempty"`
}

// DeferredResourceChange is a description of a resource change that has been
// deferred for some reason.
type DeferredResourceChange struct {
	// Reason is the reason why this resource change was deferred.
	Reason string `json:"reason,omitempty"`

	// Change contains any information we have about the deferred change.
	ResourceChange *ResourceChange `json:"resource_change,omitempty"`
}

type ActionInvocation struct {
	// Address is the absolute action address
	Address string `json:"address,omitempty"`
	// Type is the type of the action
	Type string `json:"type,omitempty"`
	// Name is the name of the action
	Name string `json:"name,omitempty"`

	// ConfigValues is the JSON representation of the values in the config block of the action
	ConfigValues    map[string]json.RawMessage `json:"config_values,omitempty"`
	ConfigSensitive json.RawMessage            `json:"config_sensitive,omitempty"`

	// ProviderName allows the property "type" to be interpreted unambiguously
	// in the unusual situation where a provider offers a type whose
	// name does not start with its own name, such as the "googlebeta" provider
	// offering "google_compute_instance".
	ProviderName string `json:"provider_name,omitempty"`

	LifecycleActionTrigger *LifecycleActionTrigger `json:"lifecycle_action_trigger,omitempty"`
	InvokeActionTrigger    *InvokeActionTrigger    `json:"invoke_action_trigger,omitempty"`
}

type LifecycleActionTrigger struct {
	TriggeringResourceAddress string `json:"triggering_resource_address,omitempty"`
	ActionTriggerEvent        string `json:"action_trigger_event,omitempty"`
	ActionTriggerBlockIndex   int    `json:"action_trigger_block_index"`
	ActionsListIndex          int    `json:"actions_list_index"`
}

type InvokeActionTrigger struct{}
