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

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