package terraform

import (
	"fmt"
	"log"
	"strings"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/gohcl"
	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/lang/marks"
	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/convert"
)

func prepareFinalInputVariableValue(addr addrs.AbsInputVariableInstance, raw *InputValue, cfg *configs.Variable) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	convertTy := cfg.ConstraintType
	log.Printf("[TRACE] prepareFinalInputVariableValue: preparing %s", addr)

	var defaultVal cty.Value
	if cfg.Default != cty.NilVal {
		log.Printf("[TRACE] prepareFinalInputVariableValue: %s has a default value", addr)
		var err error
		defaultVal, err = convert.Convert(cfg.Default, convertTy)
		if err != nil {
			// Validation of the declaration should typically catch this,
			// but we'll check it here too to be robust.
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid default value for module argument",
				Detail: fmt.Sprintf(
					"The default value for variable %q is incompatible with its type constraint: %s.",
					cfg.Name, err,
				),
				Subject: &cfg.DeclRange,
			})
			// We'll return a placeholder unknown value to avoid producing
			// redundant downstream errors.
			return cty.UnknownVal(cfg.Type), diags
		}
	}

	var sourceRange tfdiags.SourceRange
	var nonFileSource string
	if raw.HasSourceRange() {
		sourceRange = raw.SourceRange
	} else {
		// If the value came from a place that isn't a file and thus doesn't
		// have its own source range, we'll use the declaration range as
		// our source range and generate some slightly different error
		// messages.
		sourceRange = tfdiags.SourceRangeFromHCL(cfg.DeclRange)
		switch raw.SourceType {
		case ValueFromCLIArg:
			nonFileSource = fmt.Sprintf("set using -var=\"%s=...\"", addr.Variable.Name)
		case ValueFromEnvVar:
			nonFileSource = fmt.Sprintf("set using the TF_VAR_%s environment variable", addr.Variable.Name)
		case ValueFromInput:
			nonFileSource = "set using an interactive prompt"
		default:
			nonFileSource = "set from outside of the configuration"
		}
	}

	given := raw.Value
	if given == cty.NilVal { // The variable wasn't set at all (even to null)
		log.Printf("[TRACE] prepareFinalInputVariableValue: %s has no defined value", addr)
		if cfg.Required() {
			// NOTE: The CLI layer typically checks for itself whether all of
			// the required _root_ module variables are set, which would
			// mask this error with a more specific one that refers to the
			// CLI features for setting such variables. We can get here for
			// child module variables, though.
			log.Printf("[ERROR] prepareFinalInputVariableValue: %s is required but is not set", addr)
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  `Required variable not set`,
				Detail:   fmt.Sprintf(`The variable %q is required, but is not set.`, addr.Variable.Name),
				Subject:  cfg.DeclRange.Ptr(),
			})
			// We'll return a placeholder unknown value to avoid producing
			// redundant downstream errors.
			return cty.UnknownVal(cfg.Type), diags
		}

		given = defaultVal // must be set, because we checked above that the variable isn't required
	}

	// Apply defaults from the variable's type constraint to the converted value,
	// unless the converted value is null. We do not apply defaults to top-level
	// null values, as doing so could prevent assigning null to a nullable
	// variable.
	if cfg.TypeDefaults != nil && !given.IsNull() {
		given = cfg.TypeDefaults.Apply(given)
	}

	val, err := convert.Convert(given, convertTy)
	if err != nil {
		log.Printf("[ERROR] prepareFinalInputVariableValue: %s has unsuitable type\n  got:  %s\n  want: %s", addr, given.Type(), convertTy)
		var detail string
		var subject *hcl.Range
		if nonFileSource != "" {
			detail = fmt.Sprintf(
				"Unsuitable value for %s %s: %s.",
				addr, nonFileSource, err,
			)
			subject = cfg.DeclRange.Ptr()
		} else {
			detail = fmt.Sprintf(
				"The given value is not suitable for %s declared at %s: %s.",
				addr, cfg.DeclRange.String(), err,
			)
			subject = sourceRange.ToHCL().Ptr()

			// In some workflows, the operator running terraform does not have access to the variables
			// themselves. They are for example stored in encrypted files that will be used by the CI toolset
			// and not by the operator directly. In such a case, the failing secret value should not be
			// displayed to the operator
			if cfg.Sensitive {
				detail = fmt.Sprintf(
					"The given value is not suitable for %s, which is sensitive: %s. Invalid value defined at %s.",
					addr, err, sourceRange.ToHCL(),
				)
				subject = cfg.DeclRange.Ptr()
			}
		}

		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid value for input variable",
			Detail:   detail,
			Subject:  subject,
		})
		// We'll return a placeholder unknown value to avoid producing
		// redundant downstream errors.
		return cty.UnknownVal(cfg.Type), diags
	}

	// By the time we get here, we know:
	// - val matches the variable's type constraint
	// - val is definitely not cty.NilVal, but might be a null value if the given was already null.
	//
	// That means we just need to handle the case where the value is null,
	// which might mean we need to use the default value, or produce an error.
	//
	// For historical reasons we do this only for a "non-nullable" variable.
	// Nullable variables just appear as null if they were set to null,
	// regardless of any default value.
	if val.IsNull() && !cfg.Nullable {
		log.Printf("[TRACE] prepareFinalInputVariableValue: %s is defined as null", addr)
		if defaultVal != cty.NilVal {
			val = defaultVal
		} else {
			log.Printf("[ERROR] prepareFinalInputVariableValue: %s is non-nullable but set to null, and is required", addr)
			if nonFileSource != "" {
				diags = diags.Append(&hcl.Diagnostic{
					Severity: hcl.DiagError,
					Summary:  `Required variable not set`,
					Detail: fmt.Sprintf(
						"Unsuitable value for %s %s: required variable may not be set to null.",
						addr, nonFileSource,
					),
					Subject: cfg.DeclRange.Ptr(),
				})
			} else {
				diags = diags.Append(&hcl.Diagnostic{
					Severity: hcl.DiagError,
					Summary:  `Required variable not set`,
					Detail: fmt.Sprintf(
						"The given value is not suitable for %s defined at %s: required variable may not be set to null.",
						addr, cfg.DeclRange.String(),
					),
					Subject: sourceRange.ToHCL().Ptr(),
				})
			}
			// Stub out our return value so that the semantic checker doesn't
			// produce redundant downstream errors.
			val = cty.UnknownVal(cfg.Type)
		}
	}

	return val, diags
}

// evalVariableValidations ensures that all of the configured custom validations
// for a variable are passing.
//
// This must be used only after any side-effects that make the value of the
// variable available for use in expression evaluation, such as
// EvalModuleCallArgument for variables in descendent modules.
func evalVariableValidations(addr addrs.AbsInputVariableInstance, config *configs.Variable, expr hcl.Expression, ctx EvalContext) (diags tfdiags.Diagnostics) {
	if config == nil || len(config.Validations) == 0 {
		log.Printf("[TRACE] evalVariableValidations: no validation rules declared for %s, so skipping", addr)
		return nil
	}
	log.Printf("[TRACE] evalVariableValidations: validating %s", addr)

	// Variable nodes evaluate in the parent module to where they were declared
	// because the value expression (n.Expr, if set) comes from the calling
	// "module" block in the parent module.
	//
	// Validation expressions are statically validated (during configuration
	// loading) to refer only to the variable being validated, so we can
	// bypass our usual evaluation machinery here and just produce a minimal
	// evaluation context containing just the required value, and thus avoid
	// the problem that ctx's evaluation functions refer to the wrong module.
	val := ctx.GetVariableValue(addr)
	if val == cty.NilVal {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "No final value for variable",
			Detail:   fmt.Sprintf("Terraform doesn't have a final value for %s during validation. This is a bug in Terraform; please report it!", addr),
		})
		return diags
	}
	hclCtx := &hcl.EvalContext{
		Variables: map[string]cty.Value{
			"var": cty.ObjectVal(map[string]cty.Value{
				config.Name: val,
			}),
		},
		Functions: ctx.EvaluationScope(nil, EvalDataForNoInstanceKey).Functions(),
	}

	for _, validation := range config.Validations {
		const errInvalidCondition = "Invalid variable validation result"
		const errInvalidValue = "Invalid value for variable"
		var ruleDiags tfdiags.Diagnostics

		result, moreDiags := validation.Condition.Value(hclCtx)
		ruleDiags = ruleDiags.Append(moreDiags)
		errorValue, errorDiags := validation.ErrorMessage.Value(hclCtx)

		// The following error handling is a workaround to preserve backwards
		// compatibility. Due to an implementation quirk, all prior versions of
		// Terraform would treat error messages specified using JSON
		// configuration syntax (.tf.json) as string literals, even if they
		// contained the "${" template expression operator. This behaviour did
		// not match that of HCL configuration syntax, where a template
		// expression would result in a validation error.
		//
		// As a result, users writing or generating JSON configuration syntax
		// may have specified error messages which are invalid template
		// expressions. As we add support for error message expressions, we are
		// unable to perfectly distinguish between these two cases.
		//
		// To ensure that we don't break backwards compatibility, we have the
		// below fallback logic if the error message fails to evaluate. This
		// should only have any effect for JSON configurations. The gohcl
		// DecodeExpression function behaves differently when the source of the
		// expression is a JSON configuration file and a nil context is passed.
		if errorDiags.HasErrors() {
			// Attempt to decode the expression as a string literal. Passing
			// nil as the context forces a JSON syntax string value to be
			// interpreted as a string literal.
			var errorString string
			moreErrorDiags := gohcl.DecodeExpression(validation.ErrorMessage, nil, &errorString)
			if !moreErrorDiags.HasErrors() {
				// Decoding succeeded, meaning that this is a JSON syntax
				// string value. We rewrap that as a cty value to allow later
				// decoding to succeed.
				errorValue = cty.StringVal(errorString)

				// This warning diagnostic explains this odd behaviour, while
				// giving us an escape hatch to change this to a hard failure
				// in some future Terraform 1.x version.
				errorDiags = hcl.Diagnostics{
					&hcl.Diagnostic{
						Severity:    hcl.DiagWarning,
						Summary:     "Validation error message expression is invalid",
						Detail:      fmt.Sprintf("The error message provided could not be evaluated as an expression, so Terraform is interpreting it as a string literal.\n\nIn future versions of Terraform, this will be considered an error. Please file a GitHub issue if this would break your workflow.\n\n%s", errorDiags.Error()),
						Subject:     validation.ErrorMessage.Range().Ptr(),
						Context:     validation.DeclRange.Ptr(),
						Expression:  validation.ErrorMessage,
						EvalContext: hclCtx,
					},
				}
			}

			// We want to either report the original diagnostics if the
			// fallback failed, or the warning generated above if it succeeded.
			ruleDiags = ruleDiags.Append(errorDiags)
		}

		diags = diags.Append(ruleDiags)

		if ruleDiags.HasErrors() {
			log.Printf("[TRACE] evalVariableValidations: %s rule %s check rule evaluation failed: %s", addr, validation.DeclRange, ruleDiags.Err().Error())
		}
		if !result.IsKnown() {
			log.Printf("[TRACE] evalVariableValidations: %s rule %s condition value is unknown, so skipping validation for now", addr, validation.DeclRange)
			continue // We'll wait until we've learned more, then.
		}
		if result.IsNull() {
			diags = diags.Append(&hcl.Diagnostic{
				Severity:    hcl.DiagError,
				Summary:     errInvalidCondition,
				Detail:      "Validation condition expression must return either true or false, not null.",
				Subject:     validation.Condition.Range().Ptr(),
				Expression:  validation.Condition,
				EvalContext: hclCtx,
			})
			continue
		}
		var err error
		result, err = convert.Convert(result, cty.Bool)
		if err != nil {
			diags = diags.Append(&hcl.Diagnostic{
				Severity:    hcl.DiagError,
				Summary:     errInvalidCondition,
				Detail:      fmt.Sprintf("Invalid validation condition result value: %s.", tfdiags.FormatError(err)),
				Subject:     validation.Condition.Range().Ptr(),
				Expression:  validation.Condition,
				EvalContext: hclCtx,
			})
			continue
		}

		// Validation condition may be marked if the input variable is bound to
		// a sensitive value. This is irrelevant to the validation process, so
		// we discard the marks now.
		result, _ = result.Unmark()

		if result.True() {
			continue
		}

		var errorMessage string
		if !errorDiags.HasErrors() && errorValue.IsKnown() && !errorValue.IsNull() {
			var err error
			errorValue, err = convert.Convert(errorValue, cty.String)
			if err != nil {
				diags = diags.Append(&hcl.Diagnostic{
					Severity:    hcl.DiagError,
					Summary:     "Invalid error message",
					Detail:      fmt.Sprintf("Unsuitable value for error message: %s.", tfdiags.FormatError(err)),
					Subject:     validation.ErrorMessage.Range().Ptr(),
					Expression:  validation.ErrorMessage,
					EvalContext: hclCtx,
				})
			} else {
				if marks.Has(errorValue, marks.Sensitive) {
					diags = diags.Append(&hcl.Diagnostic{
						Severity: hcl.DiagError,

						Summary: "Error message refers to sensitive values",
						Detail: `The error expression used to explain this condition refers to sensitive values. Terraform will not display the resulting message.

You can correct this by removing references to sensitive values, or by carefully using the nonsensitive() function if the expression will not reveal the sensitive data.`,

						Subject:     validation.ErrorMessage.Range().Ptr(),
						Expression:  validation.ErrorMessage,
						EvalContext: hclCtx,
					})
					errorMessage = "The error message included a sensitive value, so it will not be displayed."
				} else {
					errorMessage = strings.TrimSpace(errorValue.AsString())
				}
			}
		}
		if errorMessage == "" {
			errorMessage = "Failed to evaluate condition error message."
		}

		if expr != nil {
			diags = diags.Append(&hcl.Diagnostic{
				Severity:    hcl.DiagError,
				Summary:     errInvalidValue,
				Detail:      fmt.Sprintf("%s\n\nThis was checked by the validation rule at %s.", errorMessage, validation.DeclRange.String()),
				Subject:     expr.Range().Ptr(),
				Expression:  validation.Condition,
				EvalContext: hclCtx,
			})
		} else {
			// Since we don't have a source expression for a root module
			// variable, we'll just report the error from the perspective
			// of the variable declaration itself.
			diags = diags.Append(&hcl.Diagnostic{
				Severity:    hcl.DiagError,
				Summary:     errInvalidValue,
				Detail:      fmt.Sprintf("%s\n\nThis was checked by the validation rule at %s.", errorMessage, validation.DeclRange.String()),
				Subject:     config.DeclRange.Ptr(),
				Expression:  validation.Condition,
				EvalContext: hclCtx,
			})
		}
	}

	return diags
}
