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

package tfjson

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

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

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

// ProviderSchemas represents the schemas of all providers and
// resources in use by the configuration.
type ProviderSchemas struct {
	// The version of the plan format. This should always match one of
	// ProviderSchemasFormatVersions in this package, or else
	// an unmarshal will be unstable.
	FormatVersion string `json:"format_version,omitempty"`

	// The schemas for the providers in this configuration, indexed by
	// provider type. Aliases are not included, and multiple instances
	// of a provider in configuration will be represented by a single
	// provider here.
	Schemas map[string]*ProviderSchema `json:"provider_schemas,omitempty"`
}

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

	if p.FormatVersion == "" {
		return errors.New("unexpected provider schema data, format version is missing")
	}

	constraint, err := version.NewConstraint(ProviderSchemasFormatVersionConstraints)
	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 provider schema format version: %q does not satisfy %q",
			version, constraint)
	}

	return nil
}

func (p *ProviderSchemas) UnmarshalJSON(b []byte) error {
	type rawSchemas ProviderSchemas
	var schemas rawSchemas

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

	*p = *(*ProviderSchemas)(&schemas)

	return p.Validate()
}

// ProviderSchema is the JSON representation of the schema of an
// entire provider, including the provider configuration and any
// resources and data sources included with the provider.
type ProviderSchema struct {
	// The schema for the provider's configuration.
	ConfigSchema *Schema `json:"provider,omitempty"`

	// The schemas for any resources in this provider.
	ResourceSchemas map[string]*Schema `json:"resource_schemas,omitempty"`

	// The schemas for any data sources in this provider.
	DataSourceSchemas map[string]*Schema `json:"data_source_schemas,omitempty"`

	// The schemas for any ephemeral resources in this provider.
	EphemeralResourceSchemas map[string]*Schema `json:"ephemeral_resource_schemas,omitempty"`

	// The definitions for any functions in this provider.
	Functions map[string]*FunctionSignature `json:"functions,omitempty"`
}

// Schema is the JSON representation of a particular schema
// (provider configuration, resources, data sources).
type Schema struct {
	// The version of the particular resource schema.
	Version uint64 `json:"version"`

	// The root-level block of configuration values.
	Block *SchemaBlock `json:"block,omitempty"`
}

// SchemaDescriptionKind describes the format type for a particular description's field.
type SchemaDescriptionKind string

const (
	// SchemaDescriptionKindPlain indicates a string in plain text format.
	SchemaDescriptionKindPlain SchemaDescriptionKind = "plain"

	// SchemaDescriptionKindMarkdown indicates a Markdown string and may need to be
	// processed prior to presentation.
	SchemaDescriptionKindMarkdown SchemaDescriptionKind = "markdown"
)

// SchemaBlock represents a nested block within a particular schema.
type SchemaBlock struct {
	// The attributes defined at the particular level of this block.
	Attributes map[string]*SchemaAttribute `json:"attributes,omitempty"`

	// Any nested blocks within this particular block.
	NestedBlocks map[string]*SchemaBlockType `json:"block_types,omitempty"`

	// The description for this block and format of the description. If
	// no kind is provided, it can be assumed to be plain text.
	Description     string                `json:"description,omitempty"`
	DescriptionKind SchemaDescriptionKind `json:"description_kind,omitempty"`

	// If true, this block is deprecated.
	Deprecated bool `json:"deprecated,omitempty"`
}

// SchemaNestingMode is the nesting mode for a particular nested
// schema block.
type SchemaNestingMode string

const (
	// SchemaNestingModeSingle denotes single block nesting mode, which
	// allows a single block of this specific type only in
	// configuration. This is generally the same as list or set types
	// with a single-element constraint.
	SchemaNestingModeSingle SchemaNestingMode = "single"

	// SchemaNestingModeGroup is similar to SchemaNestingModeSingle in that it
	// calls for only a single instance of a given block type with no labels,
	// but it additonally guarantees that its result will never be null,
	// even if the block is absent, and instead the nested attributes
	// and blocks will be treated as absent in that case.
	//
	// This is useful for the situation where a remote API has a feature that
	// is always enabled but has a group of settings related to that feature
	// that themselves have default values. By using SchemaNestingModeGroup
	// instead of SchemaNestingModeSingle in that case, generated plans will
	// show the block as present even when not present in configuration,
	// thus allowing any default values within to be displayed to the user.
	SchemaNestingModeGroup SchemaNestingMode = "group"

	// SchemaNestingModeList denotes list block nesting mode, which
	// allows an ordered list of blocks where duplicates are allowed.
	SchemaNestingModeList SchemaNestingMode = "list"

	// SchemaNestingModeSet denotes set block nesting mode, which
	// allows an unordered list of blocks where duplicates are
	// generally not allowed. What is considered a duplicate is up to
	// the rules of the set itself, which may or may not cover all
	// fields in the block.
	SchemaNestingModeSet SchemaNestingMode = "set"

	// SchemaNestingModeMap denotes map block nesting mode. This
	// creates a map of all declared blocks of the block type within
	// the parent, keying them on the label supplied in the block
	// declaration. This allows for blocks to be declared in the same
	// style as resources.
	SchemaNestingModeMap SchemaNestingMode = "map"
)

// SchemaBlockType describes a nested block within a schema.
type SchemaBlockType struct {
	// The nesting mode for this block.
	NestingMode SchemaNestingMode `json:"nesting_mode,omitempty"`

	// The block data for this block type, including attributes and
	// subsequent nested blocks.
	Block *SchemaBlock `json:"block,omitempty"`

	// The lower limit on items that can be declared of this block
	// type.
	MinItems uint64 `json:"min_items,omitempty"`

	// The upper limit on items that can be declared of this block
	// type.
	MaxItems uint64 `json:"max_items,omitempty"`
}

// SchemaAttribute describes an attribute within a schema block.
type SchemaAttribute struct {
	// The attribute type
	// Either AttributeType or AttributeNestedType is set, never both.
	AttributeType cty.Type `json:"type,omitempty"`

	// Details about a nested attribute type
	// Either AttributeType or AttributeNestedType is set, never both.
	AttributeNestedType *SchemaNestedAttributeType `json:"nested_type,omitempty"`

	// The description field for this attribute. If no kind is
	// provided, it can be assumed to be plain text.
	Description     string                `json:"description,omitempty"`
	DescriptionKind SchemaDescriptionKind `json:"description_kind,omitempty"`

	// If true, this attribute is deprecated.
	Deprecated bool `json:"deprecated,omitempty"`

	// If true, this attribute is required - it has to be entered in
	// configuration.
	Required bool `json:"required,omitempty"`

	// If true, this attribute is optional - it does not need to be
	// entered in configuration.
	Optional bool `json:"optional,omitempty"`

	// If true, this attribute is computed - it can be set by the
	// provider. It may also be set by configuration if Optional is
	// true.
	Computed bool `json:"computed,omitempty"`

	// If true, this attribute is sensitive and will not be displayed
	// in logs. Future versions of Terraform may encrypt or otherwise
	// treat these values with greater care than non-sensitive fields.
	Sensitive bool `json:"sensitive,omitempty"`
}

// jsonSchemaAttribute describes an attribute within a schema block
// in a middle-step internal representation before marshalled into
// a more useful SchemaAttribute with cty.Type.
//
// This avoid panic on marshalling cty.NilType (from cty upstream)
// which the default Go marshaller cannot ignore because it's a
// not nil-able struct.
type jsonSchemaAttribute struct {
	AttributeType       json.RawMessage            `json:"type,omitempty"`
	AttributeNestedType *SchemaNestedAttributeType `json:"nested_type,omitempty"`
	Description         string                     `json:"description,omitempty"`
	DescriptionKind     SchemaDescriptionKind      `json:"description_kind,omitempty"`
	Deprecated          bool                       `json:"deprecated,omitempty"`
	Required            bool                       `json:"required,omitempty"`
	Optional            bool                       `json:"optional,omitempty"`
	Computed            bool                       `json:"computed,omitempty"`
	Sensitive           bool                       `json:"sensitive,omitempty"`
}

func (as *SchemaAttribute) MarshalJSON() ([]byte, error) {
	jsonSa := &jsonSchemaAttribute{
		AttributeNestedType: as.AttributeNestedType,
		Description:         as.Description,
		DescriptionKind:     as.DescriptionKind,
		Deprecated:          as.Deprecated,
		Required:            as.Required,
		Optional:            as.Optional,
		Computed:            as.Computed,
		Sensitive:           as.Sensitive,
	}
	if as.AttributeType != cty.NilType {
		attrTy, _ := as.AttributeType.MarshalJSON()
		jsonSa.AttributeType = attrTy
	}
	return json.Marshal(jsonSa)
}

// SchemaNestedAttributeType describes a nested attribute
// which could also be just expressed simply as cty.Object(...),
// cty.List(cty.Object(...)) etc. but this allows tracking additional
// metadata which can help interpreting or validating the data.
type SchemaNestedAttributeType struct {
	// A map of nested attributes
	Attributes map[string]*SchemaAttribute `json:"attributes,omitempty"`

	// The nesting mode for this attribute.
	NestingMode SchemaNestingMode `json:"nesting_mode,omitempty"`

	// The lower limit on number of items that can be declared
	// of this attribute type (not applicable to single nesting mode).
	MinItems uint64 `json:"min_items,omitempty"`

	// The upper limit on number of items that can be declared
	// of this attribute type (not applicable to single nesting mode).
	MaxItems uint64 `json:"max_items,omitempty"`
}
