package objchange

import (
	"fmt"

	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/internal/configs/configschema"
)

// AssertPlanValid checks checks whether a planned new state returned by a
// provider's PlanResourceChange method is suitable to achieve a change
// from priorState to config. It returns a slice with nonzero length if
// any problems are detected. Because problems here indicate bugs in the
// provider that generated the plannedState, they are written with provider
// developers as an audience, rather than end-users.
//
// All of the given values must have the same type and must conform to the
// implied type of the given schema, or this function may panic or produce
// garbage results.
//
// During planning, a provider may only make changes to attributes that are
// null (unset) in the configuration and are marked as "computed" in the
// resource type schema, in order to insert any default values the provider
// may know about. If the default value cannot be determined until apply time,
// the provider can return an unknown value. Providers are forbidden from
// planning a change that disagrees with any non-null argument in the
// configuration.
//
// As a special exception, providers _are_ allowed to provide attribute values
// conflicting with configuration if and only if the planned value exactly
// matches the corresponding attribute value in the prior state. The provider
// can use this to signal that the new value is functionally equivalent to
// the old and thus no change is required.
func AssertPlanValid(schema *configschema.Block, priorState, config, plannedState cty.Value) []error {
	return assertPlanValid(schema, priorState, config, plannedState, nil)
}

func assertPlanValid(schema *configschema.Block, priorState, config, plannedState cty.Value, path cty.Path) []error {
	var errs []error
	if plannedState.IsNull() && !config.IsNull() {
		errs = append(errs, path.NewErrorf("planned for absence but config wants existence"))
		return errs
	}
	if config.IsNull() && !plannedState.IsNull() {
		errs = append(errs, path.NewErrorf("planned for existence but config wants absence"))
		return errs
	}
	if plannedState.IsNull() {
		// No further checks possible if the planned value is null
		return errs
	}

	impTy := schema.ImpliedType()

	// verify attributes
	moreErrs := assertPlannedAttrsValid(schema.Attributes, priorState, config, plannedState, path)
	errs = append(errs, moreErrs...)

	for name, blockS := range schema.BlockTypes {
		path := append(path, cty.GetAttrStep{Name: name})
		plannedV := plannedState.GetAttr(name)
		configV := config.GetAttr(name)
		priorV := cty.NullVal(impTy.AttributeType(name))
		if !priorState.IsNull() {
			priorV = priorState.GetAttr(name)
		}
		if plannedV.RawEquals(configV) {
			// Easy path: nothing has changed at all
			continue
		}

		if !configV.IsKnown() {
			// An unknown config block represents a dynamic block where the
			// for_each value is unknown, and therefor cannot be altered by the
			// provider.
			errs = append(errs, path.NewErrorf("planned value %#v for unknown dynamic block", plannedV))
			continue
		}

		if !plannedV.IsKnown() {
			// Only dynamic configuration can set blocks to unknown, so this is
			// not allowed from the provider. This means that either the config
			// and plan should match, or we have an error where the plan
			// changed the config value, both of which have been checked.
			errs = append(errs, path.NewErrorf("attribute representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
			continue
		}

		switch blockS.Nesting {
		case configschema.NestingSingle, configschema.NestingGroup:
			moreErrs := assertPlanValid(&blockS.Block, priorV, configV, plannedV, path)
			errs = append(errs, moreErrs...)
		case configschema.NestingList:
			// A NestingList might either be a list or a tuple, depending on
			// whether there are dynamically-typed attributes inside. However,
			// both support a similar-enough API that we can treat them the
			// same for our purposes here.
			if plannedV.IsNull() {
				errs = append(errs, path.NewErrorf("attribute representing a list of nested blocks must be empty to indicate no blocks, not null"))
				continue
			}

			if configV.IsNull() {
				// Configuration cannot decode a block into a null value, but
				// we could be dealing with a null returned by a legacy
				// provider and inserted via ignore_changes. Fix the value in
				// place so the length can still be compared.
				configV = cty.ListValEmpty(configV.Type().ElementType())
			}

			plannedL := plannedV.LengthInt()
			configL := configV.LengthInt()
			if plannedL != configL {
				errs = append(errs, path.NewErrorf("block count in plan (%d) disagrees with count in config (%d)", plannedL, configL))
				continue
			}

			for it := plannedV.ElementIterator(); it.Next(); {
				idx, plannedEV := it.Element()
				path := append(path, cty.IndexStep{Key: idx})
				if !plannedEV.IsKnown() {
					errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
					continue
				}
				if !configV.HasIndex(idx).True() {
					continue // should never happen since we checked the lengths above
				}
				configEV := configV.Index(idx)
				priorEV := cty.NullVal(blockS.ImpliedType())
				if !priorV.IsNull() && priorV.HasIndex(idx).True() {
					priorEV = priorV.Index(idx)
				}

				moreErrs := assertPlanValid(&blockS.Block, priorEV, configEV, plannedEV, path)
				errs = append(errs, moreErrs...)
			}
		case configschema.NestingMap:
			if plannedV.IsNull() {
				errs = append(errs, path.NewErrorf("attribute representing a map of nested blocks must be empty to indicate no blocks, not null"))
				continue
			}

			// A NestingMap might either be a map or an object, depending on
			// whether there are dynamically-typed attributes inside, but
			// that's decided statically and so all values will have the same
			// kind.
			if plannedV.Type().IsObjectType() {
				plannedAtys := plannedV.Type().AttributeTypes()
				configAtys := configV.Type().AttributeTypes()
				for k := range plannedAtys {
					if _, ok := configAtys[k]; !ok {
						errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k))
						continue
					}
					path := append(path, cty.GetAttrStep{Name: k})

					plannedEV := plannedV.GetAttr(k)
					if !plannedEV.IsKnown() {
						errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
						continue
					}
					configEV := configV.GetAttr(k)
					priorEV := cty.NullVal(blockS.ImpliedType())
					if !priorV.IsNull() && priorV.Type().HasAttribute(k) {
						priorEV = priorV.GetAttr(k)
					}
					moreErrs := assertPlanValid(&blockS.Block, priorEV, configEV, plannedEV, path)
					errs = append(errs, moreErrs...)
				}
				for k := range configAtys {
					if _, ok := plannedAtys[k]; !ok {
						errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", k))
						continue
					}
				}
			} else {
				plannedL := plannedV.LengthInt()
				configL := configV.LengthInt()
				if plannedL != configL {
					errs = append(errs, path.NewErrorf("block count in plan (%d) disagrees with count in config (%d)", plannedL, configL))
					continue
				}
				for it := plannedV.ElementIterator(); it.Next(); {
					idx, plannedEV := it.Element()
					path := append(path, cty.IndexStep{Key: idx})
					if !plannedEV.IsKnown() {
						errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
						continue
					}
					k := idx.AsString()
					if !configV.HasIndex(idx).True() {
						errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k))
						continue
					}
					configEV := configV.Index(idx)
					priorEV := cty.NullVal(blockS.ImpliedType())
					if !priorV.IsNull() && priorV.HasIndex(idx).True() {
						priorEV = priorV.Index(idx)
					}
					moreErrs := assertPlanValid(&blockS.Block, priorEV, configEV, plannedEV, path)
					errs = append(errs, moreErrs...)
				}
				for it := configV.ElementIterator(); it.Next(); {
					idx, _ := it.Element()
					if !plannedV.HasIndex(idx).True() {
						errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", idx.AsString()))
						continue
					}
				}
			}
		case configschema.NestingSet:
			if plannedV.IsNull() {
				errs = append(errs, path.NewErrorf("attribute representing a set of nested blocks must be empty to indicate no blocks, not null"))
				continue
			}

			// Because set elements have no identifier with which to correlate
			// them, we can't robustly validate the plan for a nested block
			// backed by a set, and so unfortunately we need to just trust the
			// provider to do the right thing. :(
			//
			// (In principle we could correlate elements by matching the
			// subset of attributes explicitly set in config, except for the
			// special diff suppression rule which allows for there to be a
			// planned value that is constructed by mixing part of a prior
			// value with part of a config value, creating an entirely new
			// element that is not present in either prior nor config.)
			for it := plannedV.ElementIterator(); it.Next(); {
				idx, plannedEV := it.Element()
				path := append(path, cty.IndexStep{Key: idx})
				if !plannedEV.IsKnown() {
					errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
					continue
				}
			}

		default:
			panic(fmt.Sprintf("unsupported nesting mode %s", blockS.Nesting))
		}
	}

	return errs
}

func assertPlannedAttrsValid(schema map[string]*configschema.Attribute, priorState, config, plannedState cty.Value, path cty.Path) []error {
	var errs []error
	for name, attrS := range schema {
		moreErrs := assertPlannedAttrValid(name, attrS, priorState, config, plannedState, path)
		errs = append(errs, moreErrs...)
	}
	return errs
}

func assertPlannedAttrValid(name string, attrS *configschema.Attribute, priorState, config, plannedState cty.Value, path cty.Path) []error {
	plannedV := plannedState.GetAttr(name)
	configV := config.GetAttr(name)
	priorV := cty.NullVal(attrS.Type)
	if !priorState.IsNull() {
		priorV = priorState.GetAttr(name)
	}
	path = append(path, cty.GetAttrStep{Name: name})

	return assertPlannedValueValid(attrS, priorV, configV, plannedV, path)
}

func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, plannedV cty.Value, path cty.Path) []error {

	var errs []error
	if plannedV.RawEquals(configV) {
		// This is the easy path: provider didn't change anything at all.
		return errs
	}
	if plannedV.RawEquals(priorV) && !priorV.IsNull() && !configV.IsNull() {
		// Also pretty easy: there is a prior value and the provider has
		// returned it unchanged. This indicates that configV and plannedV
		// are functionally equivalent and so the provider wishes to disregard
		// the configuration value in favor of the prior.
		return errs
	}

	switch {
	// The provider can plan any value for a computed-only attribute. There may
	// be a config value here in the case where a user used `ignore_changes` on
	// a computed attribute and ignored the warning, or we failed to validate
	// computed attributes in the config, but regardless it's not a plan error
	// caused by the provider.
	case attrS.Computed && !attrS.Optional:
		return errs

	// The provider is allowed to insert optional values when the config is
	// null, but only if the attribute is computed.
	case configV.IsNull() && attrS.Computed:
		return errs

	case configV.IsNull() && !plannedV.IsNull():
		// if the attribute is not computed, then any planned value is incorrect
		if attrS.Sensitive {
			errs = append(errs, path.NewErrorf("sensitive planned value for a non-computed attribute"))
		} else {
			errs = append(errs, path.NewErrorf("planned value %#v for a non-computed attribute", plannedV))
		}
		return errs
	}

	// If this attribute has a NestedType, validate the nested object
	if attrS.NestedType != nil {
		return assertPlannedObjectValid(attrS.NestedType, priorV, configV, plannedV, path)
	}

	// If none of the above conditions match, the provider has made an invalid
	// change to this attribute.
	if priorV.IsNull() {
		if attrS.Sensitive {
			errs = append(errs, path.NewErrorf("sensitive planned value does not match config value"))
		} else {
			errs = append(errs, path.NewErrorf("planned value %#v does not match config value %#v", plannedV, configV))
		}
		return errs
	}

	if attrS.Sensitive {
		errs = append(errs, path.NewErrorf("sensitive planned value does not match config value nor prior value"))
	} else {
		errs = append(errs, path.NewErrorf("planned value %#v does not match config value %#v nor prior value %#v", plannedV, configV, priorV))
	}

	return errs
}

func assertPlannedObjectValid(schema *configschema.Object, prior, config, planned cty.Value, path cty.Path) []error {
	var errs []error

	if planned.IsNull() && !config.IsNull() {
		errs = append(errs, path.NewErrorf("planned for absence but config wants existence"))
		return errs
	}
	if config.IsNull() && !planned.IsNull() {
		errs = append(errs, path.NewErrorf("planned for existence but config wants absence"))
		return errs
	}
	if planned.IsNull() {
		// No further checks possible if the planned value is null
		return errs
	}

	switch schema.Nesting {
	case configschema.NestingSingle, configschema.NestingGroup:
		moreErrs := assertPlannedAttrsValid(schema.Attributes, prior, config, planned, path)
		errs = append(errs, moreErrs...)

	case configschema.NestingList:
		// A NestingList might either be a list or a tuple, depending on
		// whether there are dynamically-typed attributes inside. However,
		// both support a similar-enough API that we can treat them the
		// same for our purposes here.

		plannedL := planned.LengthInt()
		configL := config.LengthInt()
		if plannedL != configL {
			errs = append(errs, path.NewErrorf("count in plan (%d) disagrees with count in config (%d)", plannedL, configL))
			return errs
		}
		for it := planned.ElementIterator(); it.Next(); {
			idx, plannedEV := it.Element()
			path := append(path, cty.IndexStep{Key: idx})
			if !config.HasIndex(idx).True() {
				continue // should never happen since we checked the lengths above
			}
			configEV := config.Index(idx)
			priorEV := cty.NullVal(schema.ImpliedType())
			if !prior.IsNull() && prior.HasIndex(idx).True() {
				priorEV = prior.Index(idx)
			}

			moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path)
			errs = append(errs, moreErrs...)
		}

	case configschema.NestingMap:
		// A NestingMap might either be a map or an object, depending on
		// whether there are dynamically-typed attributes inside, so we will
		// break these down to maps to handle them both in the same manner.
		plannedVals := map[string]cty.Value{}
		configVals := map[string]cty.Value{}
		priorVals := map[string]cty.Value{}

		if !planned.IsNull() {
			plannedVals = planned.AsValueMap()
		}
		if !config.IsNull() {
			configVals = config.AsValueMap()
		}
		if !prior.IsNull() {
			priorVals = prior.AsValueMap()
		}

		for k, plannedEV := range plannedVals {
			configEV, ok := configVals[k]
			if !ok {
				errs = append(errs, path.NewErrorf("map key %q from plan is not present in config", k))
				continue
			}
			path := append(path, cty.GetAttrStep{Name: k})

			priorEV, ok := priorVals[k]
			if !ok {
				priorEV = cty.NullVal(schema.ImpliedType())
			}
			moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path)
			errs = append(errs, moreErrs...)
		}
		for k := range configVals {
			if _, ok := plannedVals[k]; !ok {
				errs = append(errs, path.NewErrorf("map key %q from config is not present in plan", k))
				continue
			}
		}

	case configschema.NestingSet:
		plannedL := planned.LengthInt()
		configL := config.LengthInt()
		if plannedL != configL {
			errs = append(errs, path.NewErrorf("count in plan (%d) disagrees with count in config (%d)", plannedL, configL))
			return errs
		}
		// Because set elements have no identifier with which to correlate
		// them, we can't robustly validate the plan for a nested object
		// backed by a set, and so unfortunately we need to just trust the
		// provider to do the right thing.
	}

	return errs
}
