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

package tfjson

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

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

// MetadataFunctionsFormatVersionConstraints defines the versions of the JSON
// metadata functions format that are supported by this package.
var MetadataFunctionsFormatVersionConstraints = "~> 1.0"

// MetadataFunctions is the top-level object returned when exporting function
// signatures
type MetadataFunctions struct {
	// The version of the format. This should always match the
	// MetadataFunctionsFormatVersionConstraints in this package, else
	// unmarshaling will fail.
	FormatVersion string `json:"format_version"`

	// The signatures of the functions available in a Terraform version.
	Signatures map[string]*FunctionSignature `json:"function_signatures,omitempty"`
}

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

	if f.FormatVersion == "" {
		return errors.New("unexpected metadata functions data, format version is missing")
	}

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

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

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

	return nil
}

// UnmarshalJSON implements json.Unmarshaler for MetadataFunctions.
//
// As per established convention this method should only ever
// be invoked *indirectly* via [encoding/json] library.
func (f *MetadataFunctions) UnmarshalJSON(b []byte) error {
	type rawFunctions MetadataFunctions
	var functions rawFunctions

	err := json.Unmarshal(b, &functions)
	if err != nil {
		return err
	}

	*f = *(*MetadataFunctions)(&functions)

	return f.Validate()
}

// FunctionSignature represents a function signature.
type FunctionSignature struct {
	// Description is an optional human-readable description
	// of the function
	Description string `json:"description,omitempty"`

	// Summary is an optional shortened description of the function
	Summary string `json:"summary,omitempty"`

	// DeprecationMessage is an optional message that indicates that the
	// function should be considered deprecated and what actions should be
	// performed by the practitioner to handle the deprecation.
	DeprecationMessage string `json:"deprecation_message,omitempty"`

	// ReturnType is the ctyjson representation of the function's
	// return types based on supplying all parameters using
	// dynamic types. Functions can have dynamic return types.
	ReturnType cty.Type `json:"return_type"`

	// Parameters describes the function's fixed positional parameters.
	Parameters []*FunctionParameter `json:"parameters,omitempty"`

	// VariadicParameter describes the function's variadic
	// parameter if it is supported.
	VariadicParameter *FunctionParameter `json:"variadic_parameter,omitempty"`
}

// FunctionParameter represents a parameter to a function.
type FunctionParameter struct {
	// Name is an optional name for the argument.
	Name string `json:"name,omitempty"`

	// Description is an optional human-readable description
	// of the argument
	Description string `json:"description,omitempty"`

	// IsNullable is true if null is acceptable value for the argument
	IsNullable bool `json:"is_nullable,omitempty"`

	// A type that any argument for this parameter must conform to.
	Type cty.Type `json:"type"`
}
