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

	// The schemas for resources identities in this provider.
	ResourceIdentitySchemas map[string]*IdentitySchema `json:"resource_identity_schemas,omitempty"`

	// The schemas for any list resources in this provider.
	ListResourceSchemas map[string]*Schema `json:"list_resource_schemas,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"`

	// If true, this attribute is write only and its value will not be
	// persisted in artifacts such as plan files or state.
	WriteOnly bool `json:"write_only,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"`
	WriteOnly           bool                       `json:"write_only,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,
		WriteOnly:           as.WriteOnly,
	}
	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"`
}

// IdentitySchema is the JSON representation of a particular
// resource identity schema
type IdentitySchema struct {
	// The version of the particular resource identity schema.
	Version uint64 `json:"version"`

	// Map of identity attributes
	Attributes map[string]*IdentityAttribute `json:"attributes,omitempty"`
}

// IdentityAttribute describes an identity attribute
type IdentityAttribute struct {
	// The identity attribute type
	IdentityType cty.Type `json:"type,omitempty"`

	// The description of the identity attribute
	Description string `json:"description,omitempty"`

	// RequiredForImport when enabled signifies that this attribute must be
	// specified in the configuration during import
	RequiredForImport bool `json:"required_for_import,omitempty"`

	// OptionalForImport when enabled signifies that this attribute is not
	// required to be specified during import, because it can be supplied by the
	// provider
	OptionalForImport bool `json:"optional_for_import,omitempty"`
}
