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

package hcl2shim

import (
	"fmt"

	hcl2 "github.com/hashicorp/hcl/v2"
)

// SingleAttrBody is a weird implementation of hcl2.Body that acts as if
// it has a single attribute whose value is the given expression.
//
// This is used to shim Resource.RawCount and Output.RawConfig to behave
// more like they do in the old HCL loader.
type SingleAttrBody struct {
	Name string
	Expr hcl2.Expression
}

var _ hcl2.Body = SingleAttrBody{}

func (b SingleAttrBody) Content(schema *hcl2.BodySchema) (*hcl2.BodyContent, hcl2.Diagnostics) {
	content, all, diags := b.content(schema)
	if !all {
		// This should never happen because this body implementation should only
		// be used by code that is aware that it's using a single-attr body.
		diags = append(diags, &hcl2.Diagnostic{
			Severity: hcl2.DiagError,
			Summary:  "Invalid attribute",
			Detail:   fmt.Sprintf("The correct attribute name is %q.", b.Name),
			Subject:  b.Expr.Range().Ptr(),
		})
	}
	return content, diags
}

func (b SingleAttrBody) PartialContent(schema *hcl2.BodySchema) (*hcl2.BodyContent, hcl2.Body, hcl2.Diagnostics) {
	content, all, diags := b.content(schema)
	var remain hcl2.Body
	if all {
		// If the request matched the one attribute we represent, then the
		// remaining body is empty.
		remain = hcl2.EmptyBody()
	} else {
		remain = b
	}
	return content, remain, diags
}

func (b SingleAttrBody) content(schema *hcl2.BodySchema) (*hcl2.BodyContent, bool, hcl2.Diagnostics) {
	ret := &hcl2.BodyContent{}
	all := false
	var diags hcl2.Diagnostics

	for _, attrS := range schema.Attributes {
		if attrS.Name == b.Name {
			attrs, _ := b.JustAttributes()
			ret.Attributes = attrs
			all = true
		} else if attrS.Required {
			diags = append(diags, &hcl2.Diagnostic{
				Severity: hcl2.DiagError,
				Summary:  "Missing attribute",
				Detail:   fmt.Sprintf("The attribute %q is required.", attrS.Name),
				Subject:  b.Expr.Range().Ptr(),
			})
		}
	}

	return ret, all, diags
}

func (b SingleAttrBody) JustAttributes() (hcl2.Attributes, hcl2.Diagnostics) {
	return hcl2.Attributes{
		b.Name: {
			Expr:      b.Expr,
			Name:      b.Name,
			NameRange: b.Expr.Range(),
			Range:     b.Expr.Range(),
		},
	}, nil
}

func (b SingleAttrBody) MissingItemRange() hcl2.Range {
	return b.Expr.Range()
}
