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
}

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"`

	// 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"`
}
