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

package states

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

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
)

// ResourceInstanceObjectSrc is a not-fully-decoded version of
// ResourceInstanceObject. Decoding of it can be completed by first handling
// any schema migration steps to get to the latest schema version and then
// calling method Decode with the implied type of the latest schema.
type ResourceInstanceObjectSrc struct {
	// SchemaVersion is the resource-type-specific schema version number that
	// was current when either AttrsJSON or AttrsFlat was encoded. Migration
	// steps are required if this is less than the current version number
	// reported by the corresponding provider.
	SchemaVersion uint64

	// AttrsJSON is a JSON-encoded representation of the object attributes,
	// encoding the value (of the object type implied by the associated resource
	// type schema) that represents this remote object in Terraform Language
	// expressions, and is compared with configuration when producing a diff.
	//
	// This is retained in JSON format here because it may require preprocessing
	// before decoding if, for example, the stored attributes are for an older
	// schema version which the provider must upgrade before use. If the
	// version is current, it is valid to simply decode this using the
	// type implied by the current schema, without the need for the provider
	// to perform an upgrade first.
	//
	// When writing a ResourceInstanceObject into the state, AttrsJSON should
	// always be conformant to the current schema version and the current
	// schema version should be recorded in the SchemaVersion field.
	AttrsJSON []byte

	// AttrsFlat is a legacy form of attributes used in older state file
	// formats, and in the new state format for objects that haven't yet been
	// upgraded. This attribute is mutually exclusive with Attrs: for any
	// ResourceInstanceObject, only one of these attributes may be populated
	// and the other must be nil.
	//
	// An instance object with this field populated should be upgraded to use
	// Attrs at the earliest opportunity, since this legacy flatmap-based
	// format will be phased out over time. AttrsFlat should not be used when
	// writing new or updated objects to state; instead, callers must follow
	// the recommendations in the AttrsJSON documentation above.
	AttrsFlat map[string]string

	// AttrSensitivePaths is an array of paths to mark as sensitive coming out of
	// state, or to save as sensitive paths when saving state
	AttrSensitivePaths []cty.PathValueMarks

	// These fields all correspond to the fields of the same name on
	// ResourceInstanceObject.
	Private             []byte
	Status              ObjectStatus
	Dependencies        []addrs.ConfigResource
	CreateBeforeDestroy bool
}

// Decode unmarshals the raw representation of the object attributes. Pass the
// implied type of the corresponding resource type schema for correct operation.
//
// Before calling Decode, the caller must check that the SchemaVersion field
// exactly equals the version number of the schema whose implied type is being
// passed, or else the result is undefined.
//
// The returned object may share internal references with the receiver and
// so the caller must not mutate the receiver any further once once this
// method is called.
func (os *ResourceInstanceObjectSrc) Decode(ty cty.Type) (*ResourceInstanceObject, error) {
	var val cty.Value
	var err error
	if os.AttrsFlat != nil {
		// Legacy mode. We'll do our best to unpick this from the flatmap.
		val, err = hcl2shim.HCL2ValueFromFlatmap(os.AttrsFlat, ty)
		if err != nil {
			return nil, err
		}
	} else {
		val, err = ctyjson.Unmarshal(os.AttrsJSON, ty)
		// Mark the value with paths if applicable
		if os.AttrSensitivePaths != nil {
			val = val.MarkWithPaths(os.AttrSensitivePaths)
		}
		if err != nil {
			return nil, err
		}
	}

	return &ResourceInstanceObject{
		Value:               val,
		Status:              os.Status,
		Dependencies:        os.Dependencies,
		Private:             os.Private,
		CreateBeforeDestroy: os.CreateBeforeDestroy,
	}, nil
}

// CompleteUpgrade creates a new ResourceInstanceObjectSrc by copying the
// metadata from the receiver and writing in the given new schema version
// and attribute value that are presumed to have resulted from upgrading
// from an older schema version.
func (os *ResourceInstanceObjectSrc) CompleteUpgrade(newAttrs cty.Value, newType cty.Type, newSchemaVersion uint64) (*ResourceInstanceObjectSrc, error) {
	new := os.DeepCopy()
	new.AttrsFlat = nil // We always use JSON after an upgrade, even if the source used flatmap

	// This is the same principle as ResourceInstanceObject.Encode, but
	// avoiding a decode/re-encode cycle because we don't have type info
	// available for the "old" attributes.
	newAttrs = cty.UnknownAsNull(newAttrs)
	src, err := ctyjson.Marshal(newAttrs, newType)
	if err != nil {
		return nil, err
	}

	new.AttrsJSON = src
	new.SchemaVersion = newSchemaVersion
	return new, nil
}
