package blocktoattr

import (
	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/zclconf/go-cty/cty"
)

func ambiguousNames(schema *configschema.Block) map[string]struct{} {
	if schema == nil {
		return nil
	}
	ambiguousNames := make(map[string]struct{})
	for name, attrS := range schema.Attributes {
		aty := attrS.Type
		if (aty.IsListType() || aty.IsSetType()) && aty.ElementType().IsObjectType() {
			ambiguousNames[name] = struct{}{}
		}
	}
	return ambiguousNames
}

func effectiveSchema(given *hcl.BodySchema, body hcl.Body, ambiguousNames map[string]struct{}, dynamicExpanded bool) *hcl.BodySchema {
	ret := &hcl.BodySchema{}

	appearsAsBlock := make(map[string]struct{})
	{
		// We'll construct some throwaway schemas here just to probe for
		// whether each of our ambiguous names seems to be being used as
		// an attribute or a block. We need to check both because in JSON
		// syntax we rely on the schema to decide between attribute or block
		// interpretation and so JSON will always answer yes to both of
		// these questions and we want to prefer the attribute interpretation
		// in that case.
		var probeSchema hcl.BodySchema

		for name := range ambiguousNames {
			probeSchema = hcl.BodySchema{
				Attributes: []hcl.AttributeSchema{
					{
						Name: name,
					},
				},
			}
			content, _, _ := body.PartialContent(&probeSchema)
			if _, exists := content.Attributes[name]; exists {
				// Can decode as an attribute, so we'll go with that.
				continue
			}
			probeSchema = hcl.BodySchema{
				Blocks: []hcl.BlockHeaderSchema{
					{
						Type: name,
					},
				},
			}
			content, _, _ = body.PartialContent(&probeSchema)
			if len(content.Blocks) > 0 || dynamicExpanded {
				// A dynamic block with an empty iterator returns nothing.
				// If there's no attribute and we have either a block or a
				// dynamic expansion, we need to rewrite this one as a
				// block for a successful result.
				appearsAsBlock[name] = struct{}{}
			}
		}
		if !dynamicExpanded {
			// If we're deciding for a context where dynamic blocks haven't
			// been expanded yet then we need to probe for those too.
			probeSchema = hcl.BodySchema{
				Blocks: []hcl.BlockHeaderSchema{
					{
						Type:       "dynamic",
						LabelNames: []string{"type"},
					},
				},
			}
			content, _, _ := body.PartialContent(&probeSchema)
			for _, block := range content.Blocks {
				if _, exists := ambiguousNames[block.Labels[0]]; exists {
					appearsAsBlock[block.Labels[0]] = struct{}{}
				}
			}
		}
	}

	for _, attrS := range given.Attributes {
		if _, exists := appearsAsBlock[attrS.Name]; exists {
			ret.Blocks = append(ret.Blocks, hcl.BlockHeaderSchema{
				Type: attrS.Name,
			})
		} else {
			ret.Attributes = append(ret.Attributes, attrS)
		}
	}

	// Anything that is specified as a block type in the input schema remains
	// that way by just passing through verbatim.
	ret.Blocks = append(ret.Blocks, given.Blocks...)

	return ret
}

// SchemaForCtyElementType converts a cty object type into an
// approximately-equivalent configschema.Block representing the element of
// a list or set. If the given type is not an object type then this
// function will panic.
func SchemaForCtyElementType(ty cty.Type) *configschema.Block {
	atys := ty.AttributeTypes()
	ret := &configschema.Block{
		Attributes: make(map[string]*configschema.Attribute, len(atys)),
	}
	for name, aty := range atys {
		ret.Attributes[name] = &configschema.Attribute{
			Type:     aty,
			Optional: true,
		}
	}
	return ret
}

// SchemaForCtyContainerType converts a cty list-of-object or set-of-object type
// into an approximately-equivalent configschema.NestedBlock. If the given type
// is not of the expected kind then this function will panic.
func SchemaForCtyContainerType(ty cty.Type) *configschema.NestedBlock {
	var nesting configschema.NestingMode
	switch {
	case ty.IsListType():
		nesting = configschema.NestingList
	case ty.IsSetType():
		nesting = configschema.NestingSet
	default:
		panic("unsuitable type")
	}
	nested := SchemaForCtyElementType(ty.ElementType())
	return &configschema.NestedBlock{
		Nesting: nesting,
		Block:   *nested,
	}
}

// TypeCanBeBlocks returns true if the given type is a list-of-object or
// set-of-object type, and would thus be subject to the blocktoattr fixup
// if used as an attribute type.
func TypeCanBeBlocks(ty cty.Type) bool {
	return (ty.IsListType() || ty.IsSetType()) && ty.ElementType().IsObjectType()
}
