// Copyright IBM Corp. 2019, 2026
// SPDX-License-Identifier: MPL-2.0

package tfjson

import "encoding/json"

type unknownConstantValue struct{}

// UnknownConstantValue is a singleton type that denotes that a
// constant value is explicitly unknown. This is set during an
// unmarshal when references are found in an expression to help more
// explicitly differentiate between an explicit null and unknown
// value.
var UnknownConstantValue = &unknownConstantValue{}

// Expression describes the format for an individual key in a
// Terraform configuration.
//
// This struct wraps ExpressionData to support custom JSON parsing.
type Expression struct {
	*ExpressionData
}

// ExpressionData describes the format for an individual key in a
// Terraform configuration.
type ExpressionData struct {
	// If the *entire* expression is a constant-defined value, this
	// will contain the Go representation of the expression's data.
	//
	// Note that a nil here denotes and explicit null. When a value is
	// unknown on part of the value coming from an expression that
	// cannot be resolved at parse time, this field will contain
	// UnknownConstantValue.
	ConstantValue interface{} `json:"constant_value,omitempty"`

	// If any part of the expression contained values that were not
	// able to be resolved at parse-time, this will contain a list of
	// the referenced identifiers that caused the value to be unknown.
	References []string `json:"references,omitempty"`

	// A list of complex objects that were nested in this expression.
	// If this value is a nested block in configuration, sometimes
	// referred to as a "sub-resource", this field will contain those
	// values, and ConstantValue and References will be blank.
	NestedBlocks []map[string]*Expression `json:"-"`
}

// UnmarshalJSON implements json.Unmarshaler for Expression.
//
// As per established convention this method should only ever
// be invoked *indirectly* via [encoding/json] library.
func (e *Expression) UnmarshalJSON(b []byte) error {
	result := new(ExpressionData)

	// Check to see if this is an array first. If it is, this is more
	// than likely a list of nested blocks.
	var rawNested []map[string]json.RawMessage
	if err := json.Unmarshal(b, &rawNested); err == nil {
		result.NestedBlocks, err = unmarshalExpressionBlocks(rawNested)
		if err != nil {
			return err
		}
	} else {
		// It's a non-nested expression block, parse normally
		if err := json.Unmarshal(b, &result); err != nil {
			return err
		}

		// If References is non-zero, then ConstantValue is unknown. Set
		// this explicitly.
		if len(result.References) > 0 {
			result.ConstantValue = UnknownConstantValue
		}
	}

	e.ExpressionData = result
	return nil
}

func unmarshalExpressionBlocks(raw []map[string]json.RawMessage) ([]map[string]*Expression, error) {
	var result []map[string]*Expression

	for _, rawBlock := range raw {
		block := make(map[string]*Expression)
		for k, rawExpr := range rawBlock {
			var expr *Expression
			if err := json.Unmarshal(rawExpr, &expr); err != nil {
				return nil, err
			}

			block[k] = expr
		}

		result = append(result, block)
	}

	return result, nil
}

// MarshalJSON implements json.Marshaler for Expression.
func (e *Expression) MarshalJSON() ([]byte, error) {
	switch {
	case len(e.ExpressionData.NestedBlocks) > 0:
		return marshalExpressionBlocks(e.ExpressionData.NestedBlocks)

	case e.ExpressionData.ConstantValue == UnknownConstantValue:
		return json.Marshal(&ExpressionData{
			References: e.ExpressionData.References,
		})
	}

	return json.Marshal(e.ExpressionData)
}

func marshalExpressionBlocks(nested []map[string]*Expression) ([]byte, error) {
	var rawNested []map[string]json.RawMessage
	for _, block := range nested {
		rawBlock := make(map[string]json.RawMessage)
		for k, expr := range block {
			raw, err := json.Marshal(expr)
			if err != nil {
				return nil, err
			}

			rawBlock[k] = raw
		}

		rawNested = append(rawNested, rawBlock)
	}

	return json.Marshal(rawNested)
}
