package schema

import (
	"context"
	"fmt"

	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
	"github.com/hashicorp/terraform/internal/legacy/terraform"
	ctyconvert "github.com/zclconf/go-cty/cty/convert"
)

// Backend represents a partial backend.Backend implementation and simplifies
// the creation of configuration loading and validation.
//
// Unlike other schema structs such as Provider, this struct is meant to be
// embedded within your actual implementation. It provides implementations
// only for Input and Configure and gives you a method for accessing the
// configuration in the form of a ResourceData that you're expected to call
// from the other implementation funcs.
type Backend struct {
	// Schema is the schema for the configuration of this backend. If this
	// Backend has no configuration this can be omitted.
	Schema map[string]*Schema

	// ConfigureFunc is called to configure the backend. Use the
	// FromContext* methods to extract information from the context.
	// This can be nil, in which case nothing will be called but the
	// config will still be stored.
	ConfigureFunc func(context.Context) error

	config *ResourceData
}

var (
	backendConfigKey = contextKey("backend config")
)

// FromContextBackendConfig extracts a ResourceData with the configuration
// from the context. This should only be called by Backend functions.
func FromContextBackendConfig(ctx context.Context) *ResourceData {
	return ctx.Value(backendConfigKey).(*ResourceData)
}

func (b *Backend) ConfigSchema() *configschema.Block {
	// This is an alias of CoreConfigSchema just to implement the
	// backend.Backend interface.
	return b.CoreConfigSchema()
}

func (b *Backend) PrepareConfig(configVal cty.Value) (cty.Value, tfdiags.Diagnostics) {
	if b == nil {
		return configVal, nil
	}
	var diags tfdiags.Diagnostics
	var err error

	// In order to use Transform below, this needs to be filled out completely
	// according the schema.
	configVal, err = b.CoreConfigSchema().CoerceValue(configVal)
	if err != nil {
		return configVal, diags.Append(err)
	}

	// lookup any required, top-level attributes that are Null, and see if we
	// have a Default value available.
	configVal, err = cty.Transform(configVal, func(path cty.Path, val cty.Value) (cty.Value, error) {
		// we're only looking for top-level attributes
		if len(path) != 1 {
			return val, nil
		}

		// nothing to do if we already have a value
		if !val.IsNull() {
			return val, nil
		}

		// get the Schema definition for this attribute
		getAttr, ok := path[0].(cty.GetAttrStep)
		// these should all exist, but just ignore anything strange
		if !ok {
			return val, nil
		}

		attrSchema := b.Schema[getAttr.Name]
		// continue to ignore anything that doesn't match
		if attrSchema == nil {
			return val, nil
		}

		// this is deprecated, so don't set it
		if attrSchema.Deprecated != "" || attrSchema.Removed != "" {
			return val, nil
		}

		// find a default value if it exists
		def, err := attrSchema.DefaultValue()
		if err != nil {
			diags = diags.Append(fmt.Errorf("error getting default for %q: %s", getAttr.Name, err))
			return val, err
		}

		// no default
		if def == nil {
			return val, nil
		}

		// create a cty.Value and make sure it's the correct type
		tmpVal := hcl2shim.HCL2ValueFromConfigValue(def)

		// helper/schema used to allow setting "" to a bool
		if val.Type() == cty.Bool && tmpVal.RawEquals(cty.StringVal("")) {
			// return a warning about the conversion
			diags = diags.Append("provider set empty string as default value for bool " + getAttr.Name)
			tmpVal = cty.False
		}

		val, err = ctyconvert.Convert(tmpVal, val.Type())
		if err != nil {
			diags = diags.Append(fmt.Errorf("error setting default for %q: %s", getAttr.Name, err))
		}

		return val, err
	})
	if err != nil {
		// any error here was already added to the diagnostics
		return configVal, diags
	}

	shimRC := b.shimConfig(configVal)
	warns, errs := schemaMap(b.Schema).Validate(shimRC)
	for _, warn := range warns {
		diags = diags.Append(tfdiags.SimpleWarning(warn))
	}
	for _, err := range errs {
		diags = diags.Append(err)
	}
	return configVal, diags
}

func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics {
	if b == nil {
		return nil
	}

	var diags tfdiags.Diagnostics
	sm := schemaMap(b.Schema)
	shimRC := b.shimConfig(obj)

	// Get a ResourceData for this configuration. To do this, we actually
	// generate an intermediary "diff" although that is never exposed.
	diff, err := sm.Diff(nil, shimRC, nil, nil, true)
	if err != nil {
		diags = diags.Append(err)
		return diags
	}

	data, err := sm.Data(nil, diff)
	if err != nil {
		diags = diags.Append(err)
		return diags
	}
	b.config = data

	if b.ConfigureFunc != nil {
		err = b.ConfigureFunc(context.WithValue(
			context.Background(), backendConfigKey, data))
		if err != nil {
			diags = diags.Append(err)
			return diags
		}
	}

	return diags
}

// shimConfig turns a new-style cty.Value configuration (which must be of
// an object type) into a minimal old-style *terraform.ResourceConfig object
// that should be populated enough to appease the not-yet-updated functionality
// in this package. This should be removed once everything is updated.
func (b *Backend) shimConfig(obj cty.Value) *terraform.ResourceConfig {
	shimMap, ok := hcl2shim.ConfigValueFromHCL2(obj).(map[string]interface{})
	if !ok {
		// If the configVal was nil, we still want a non-nil map here.
		shimMap = map[string]interface{}{}
	}
	return &terraform.ResourceConfig{
		Config: shimMap,
		Raw:    shimMap,
	}
}

// Config returns the configuration. This is available after Configure is
// called.
func (b *Backend) Config() *ResourceData {
	return b.config
}
