package local

import (
	"context"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/hashicorp/terraform/internal/backend"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/configs/configload"
	"github.com/hashicorp/terraform/internal/plans/planfile"
	"github.com/hashicorp/terraform/internal/states/statemgr"
	"github.com/hashicorp/terraform/internal/terraform"
	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/zclconf/go-cty/cty"
)

// backend.Local implementation.
func (b *Local) LocalRun(op *backend.Operation) (*backend.LocalRun, statemgr.Full, tfdiags.Diagnostics) {
	// Make sure the type is invalid. We use this as a way to know not
	// to ask for input/validate. We're modifying this through a pointer,
	// so we're mutating an object that belongs to the caller here, which
	// seems bad but we're preserving it for now until we have time to
	// properly design this API, vs. just preserving whatever it currently
	// happens to do.
	op.Type = backend.OperationTypeInvalid

	op.StateLocker = op.StateLocker.WithContext(context.Background())

	lr, _, stateMgr, diags := b.localRun(op)
	return lr, stateMgr, diags
}

func (b *Local) localRun(op *backend.Operation) (*backend.LocalRun, *configload.Snapshot, statemgr.Full, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	// Get the latest state.
	log.Printf("[TRACE] backend/local: requesting state manager for workspace %q", op.Workspace)
	s, err := b.StateMgr(op.Workspace)
	if err != nil {
		diags = diags.Append(fmt.Errorf("error loading state: %w", err))
		return nil, nil, nil, diags
	}
	log.Printf("[TRACE] backend/local: requesting state lock for workspace %q", op.Workspace)
	if diags := op.StateLocker.Lock(s, op.Type.String()); diags.HasErrors() {
		return nil, nil, nil, diags
	}

	defer func() {
		// If we're returning with errors, and thus not producing a valid
		// context, we'll want to avoid leaving the workspace locked.
		if diags.HasErrors() {
			diags = diags.Append(op.StateLocker.Unlock())
		}
	}()

	log.Printf("[TRACE] backend/local: reading remote state for workspace %q", op.Workspace)
	if err := s.RefreshState(); err != nil {
		diags = diags.Append(fmt.Errorf("error loading state: %w", err))
		return nil, nil, nil, diags
	}

	ret := &backend.LocalRun{}

	// Initialize our context options
	var coreOpts terraform.ContextOpts
	if v := b.ContextOpts; v != nil {
		coreOpts = *v
	}
	coreOpts.UIInput = op.UIIn
	coreOpts.Hooks = op.Hooks

	var ctxDiags tfdiags.Diagnostics
	var configSnap *configload.Snapshot
	if op.PlanFile != nil {
		var stateMeta *statemgr.SnapshotMeta
		// If the statemgr implements our optional PersistentMeta interface then we'll
		// additionally verify that the state snapshot in the plan file has
		// consistent metadata, as an additional safety check.
		if sm, ok := s.(statemgr.PersistentMeta); ok {
			m := sm.StateSnapshotMeta()
			stateMeta = &m
		}
		log.Printf("[TRACE] backend/local: populating backend.LocalRun from plan file")
		ret, configSnap, ctxDiags = b.localRunForPlanFile(op, op.PlanFile, ret, &coreOpts, stateMeta)
		if ctxDiags.HasErrors() {
			diags = diags.Append(ctxDiags)
			return nil, nil, nil, diags
		}

		// Write sources into the cache of the main loader so that they are
		// available if we need to generate diagnostic message snippets.
		op.ConfigLoader.ImportSourcesFromSnapshot(configSnap)
	} else {
		log.Printf("[TRACE] backend/local: populating backend.LocalRun for current working directory")
		ret, configSnap, ctxDiags = b.localRunDirect(op, ret, &coreOpts, s)
	}
	diags = diags.Append(ctxDiags)
	if diags.HasErrors() {
		return nil, nil, nil, diags
	}

	// If we have an operation, then we automatically do the input/validate
	// here since every option requires this.
	if op.Type != backend.OperationTypeInvalid {
		// If input asking is enabled, then do that
		if op.PlanFile == nil && b.OpInput {
			mode := terraform.InputModeProvider

			log.Printf("[TRACE] backend/local: requesting interactive input, if necessary")
			inputDiags := ret.Core.Input(ret.Config, mode)
			diags = diags.Append(inputDiags)
			if inputDiags.HasErrors() {
				return nil, nil, nil, diags
			}
		}

		// If validation is enabled, validate
		if b.OpValidation {
			log.Printf("[TRACE] backend/local: running validation operation")
			validateDiags := ret.Core.Validate(ret.Config)
			diags = diags.Append(validateDiags)
		}
	}

	return ret, configSnap, s, diags
}

func (b *Local) localRunDirect(op *backend.Operation, run *backend.LocalRun, coreOpts *terraform.ContextOpts, s statemgr.Full) (*backend.LocalRun, *configload.Snapshot, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	// Load the configuration using the caller-provided configuration loader.
	config, configSnap, configDiags := op.ConfigLoader.LoadConfigWithSnapshot(op.ConfigDir)
	diags = diags.Append(configDiags)
	if configDiags.HasErrors() {
		return nil, nil, diags
	}
	run.Config = config

	if errs := config.VerifyDependencySelections(op.DependencyLocks); len(errs) > 0 {
		var buf strings.Builder
		for _, err := range errs {
			fmt.Fprintf(&buf, "\n  - %s", err.Error())
		}
		var suggestion string
		switch {
		case op.DependencyLocks == nil:
			// If we get here then it suggests that there's a caller that we
			// didn't yet update to populate DependencyLocks, which is a bug.
			suggestion = "This run has no dependency lock information provided at all, which is a bug in Terraform; please report it!"
		case op.DependencyLocks.Empty():
			suggestion = "To make the initial dependency selections that will initialize the dependency lock file, run:\n  terraform init"
		default:
			suggestion = "To update the locked dependency selections to match a changed configuration, run:\n  terraform init -upgrade"
		}
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Inconsistent dependency lock file",
			fmt.Sprintf(
				"The following dependency selections recorded in the lock file are inconsistent with the current configuration:%s\n\n%s",
				buf.String(), suggestion,
			),
		))
	}

	var rawVariables map[string]backend.UnparsedVariableValue
	if op.AllowUnsetVariables {
		// Rather than prompting for input, we'll just stub out the required
		// but unset variables with unknown values to represent that they are
		// placeholders for values the user would need to provide for other
		// operations.
		rawVariables = b.stubUnsetRequiredVariables(op.Variables, config.Module.Variables)
	} else {
		// If interactive input is enabled, we might gather some more variable
		// values through interactive prompts.
		// TODO: Need to route the operation context through into here, so that
		// the interactive prompts can be sensitive to its timeouts/etc.
		rawVariables = b.interactiveCollectVariables(context.TODO(), op.Variables, config.Module.Variables, op.UIIn)
	}

	variables, varDiags := backend.ParseVariableValues(rawVariables, config.Module.Variables)
	diags = diags.Append(varDiags)
	if diags.HasErrors() {
		return nil, nil, diags
	}

	planOpts := &terraform.PlanOpts{
		Mode:         op.PlanMode,
		Targets:      op.Targets,
		ForceReplace: op.ForceReplace,
		SetVariables: variables,
		SkipRefresh:  op.Type != backend.OperationTypeRefresh && !op.PlanRefresh,
	}
	run.PlanOpts = planOpts

	// For a "direct" local run, the input state is the most recently stored
	// snapshot, from the previous run.
	run.InputState = s.State()

	tfCtx, moreDiags := terraform.NewContext(coreOpts)
	diags = diags.Append(moreDiags)
	if moreDiags.HasErrors() {
		return nil, nil, diags
	}
	run.Core = tfCtx
	return run, configSnap, diags
}

func (b *Local) localRunForPlanFile(op *backend.Operation, pf *planfile.Reader, run *backend.LocalRun, coreOpts *terraform.ContextOpts, currentStateMeta *statemgr.SnapshotMeta) (*backend.LocalRun, *configload.Snapshot, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	const errSummary = "Invalid plan file"

	// A plan file has a snapshot of configuration embedded inside it, which
	// is used instead of whatever configuration might be already present
	// in the filesystem.
	snap, err := pf.ReadConfigSnapshot()
	if err != nil {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			errSummary,
			fmt.Sprintf("Failed to read configuration snapshot from plan file: %s.", err),
		))
		return nil, snap, diags
	}
	loader := configload.NewLoaderFromSnapshot(snap)
	config, configDiags := loader.LoadConfig(snap.Modules[""].Dir)
	diags = diags.Append(configDiags)
	if configDiags.HasErrors() {
		return nil, snap, diags
	}
	run.Config = config

	// NOTE: We're intentionally comparing the current locks with the
	// configuration snapshot, rather than the lock snapshot in the plan file,
	// because it's the current locks which dictate our plugin selections
	// in coreOpts below. However, we'll also separately check that the
	// plan file has identical locked plugins below, and thus we're effectively
	// checking consistency with both here.
	if errs := config.VerifyDependencySelections(op.DependencyLocks); len(errs) > 0 {
		var buf strings.Builder
		for _, err := range errs {
			fmt.Fprintf(&buf, "\n  - %s", err.Error())
		}
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Inconsistent dependency lock file",
			fmt.Sprintf(
				"The following dependency selections recorded in the lock file are inconsistent with the configuration in the saved plan:%s\n\nA saved plan can be applied only to the same configuration it was created from. Create a new plan from the updated configuration.",
				buf.String(),
			),
		))
	}

	// This check is an important complement to the check above: the locked
	// dependencies in the configuration must match the configuration, and
	// the locked dependencies in the plan must match the locked dependencies
	// in the configuration, and so transitively we ensure that the locked
	// dependencies in the plan match the configuration too. However, this
	// additionally catches any inconsistency between the two sets of locks
	// even if they both happen to be valid per the current configuration,
	// which is one of several ways we try to catch the mistake of applying
	// a saved plan file in a different place than where we created it.
	depLocksFromPlan, moreDiags := pf.ReadDependencyLocks()
	diags = diags.Append(moreDiags)
	if depLocksFromPlan != nil && !op.DependencyLocks.Equal(depLocksFromPlan) {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Inconsistent dependency lock file",
			"The given plan file was created with a different set of external dependency selections than the current configuration. A saved plan can be applied only to the same configuration it was created from.\n\nCreate a new plan from the updated configuration.",
		))
	}

	// A plan file also contains a snapshot of the prior state the changes
	// are intended to apply to.
	priorStateFile, err := pf.ReadStateFile()
	if err != nil {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			errSummary,
			fmt.Sprintf("Failed to read prior state snapshot from plan file: %s.", err),
		))
		return nil, snap, diags
	}

	if currentStateMeta != nil {
		// If the caller sets this, we require that the stored prior state
		// has the same metadata, which is an extra safety check that nothing
		// has changed since the plan was created. (All of the "real-world"
		// state manager implementations support this, but simpler test backends
		// may not.)

		// Because the plan always contains a state, even if it is empty, the
		// first plan to be applied will have empty snapshot metadata. In this
		// case we compare only the serial in order to provide a more correct
		// error.
		firstPlan := priorStateFile.Lineage == "" && priorStateFile.Serial == 0

		switch {
		case !firstPlan && priorStateFile.Lineage != currentStateMeta.Lineage:
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Saved plan does not match the given state",
				"The given plan file can not be applied because it was created from a different state lineage.",
			))

		case priorStateFile.Serial != currentStateMeta.Serial:
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Saved plan is stale",
				"The given plan file can no longer be applied because the state was changed by another operation after the plan was created.",
			))
		}
	}
	// When we're applying a saved plan, the input state is the "prior state"
	// recorded in the plan, which incorporates the result of all of the
	// refreshing we did while building the plan.
	run.InputState = priorStateFile.State

	plan, err := pf.ReadPlan()
	if err != nil {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			errSummary,
			fmt.Sprintf("Failed to read plan from plan file: %s.", err),
		))
		return nil, snap, diags
	}
	// When we're applying a saved plan, we populate Plan instead of PlanOpts,
	// because a plan object incorporates the subset of data from PlanOps that
	// we need to apply the plan.
	run.Plan = plan

	tfCtx, moreDiags := terraform.NewContext(coreOpts)
	diags = diags.Append(moreDiags)
	if moreDiags.HasErrors() {
		return nil, nil, diags
	}
	run.Core = tfCtx
	return run, snap, diags
}

// interactiveCollectVariables attempts to complete the given existing
// map of variables by interactively prompting for any variables that are
// declared as required but not yet present.
//
// If interactive input is disabled for this backend instance then this is
// a no-op. If input is enabled but fails for some reason, the resulting
// map will be incomplete. For these reasons, the caller must still validate
// that the result is complete and valid.
//
// This function does not modify the map given in "existing", but may return
// it unchanged if no modifications are required. If modifications are required,
// the result is a new map with all of the elements from "existing" plus
// additional elements as appropriate.
//
// Interactive prompting is a "best effort" thing for first-time user UX and
// not something we expect folks to be relying on for routine use. Terraform
// is primarily a non-interactive tool and so we prefer to report in error
// messages that variables are not set rather than reporting that input failed:
// the primary resolution to missing variables is to provide them by some other
// means.
func (b *Local) interactiveCollectVariables(ctx context.Context, existing map[string]backend.UnparsedVariableValue, vcs map[string]*configs.Variable, uiInput terraform.UIInput) map[string]backend.UnparsedVariableValue {
	var needed []string
	if b.OpInput && uiInput != nil {
		for name, vc := range vcs {
			if !vc.Required() {
				continue // We only prompt for required variables
			}
			if _, exists := existing[name]; !exists {
				needed = append(needed, name)
			}
		}
	} else {
		log.Print("[DEBUG] backend/local: Skipping interactive prompts for variables because input is disabled")
	}
	if len(needed) == 0 {
		return existing
	}

	log.Printf("[DEBUG] backend/local: will prompt for input of unset required variables %s", needed)

	// If we get here then we're planning to prompt for at least one additional
	// variable's value.
	sort.Strings(needed) // prompt in lexical order
	ret := make(map[string]backend.UnparsedVariableValue, len(vcs))
	for k, v := range existing {
		ret[k] = v
	}
	for _, name := range needed {
		vc := vcs[name]
		rawValue, err := uiInput.Input(ctx, &terraform.InputOpts{
			Id:          fmt.Sprintf("var.%s", name),
			Query:       fmt.Sprintf("var.%s", name),
			Description: vc.Description,
			Secret:      vc.Sensitive,
		})
		if err != nil {
			// Since interactive prompts are best-effort, we'll just continue
			// here and let subsequent validation report this as a variable
			// not specified.
			log.Printf("[WARN] backend/local: Failed to request user input for variable %q: %s", name, err)
			continue
		}
		ret[name] = unparsedInteractiveVariableValue{Name: name, RawValue: rawValue}
	}
	return ret
}

// stubUnsetVariables ensures that all required variables defined in the
// configuration exist in the resulting map, by adding new elements as necessary.
//
// The stubbed value of any additions will be an unknown variable conforming
// to the variable's configured type constraint, meaning that no particular
// value is known and that one must be provided by the user in order to get
// a complete result.
//
// Unset optional attributes (those with default values) will not be populated
// by this function, under the assumption that a later step will handle those.
// In this sense, stubUnsetRequiredVariables is essentially a non-interactive,
// non-error-producing variant of interactiveCollectVariables that creates
// placeholders for values the user would be prompted for interactively on
// other operations.
//
// This function should be used only in situations where variables values
// will not be directly used and the variables map is being constructed only
// to produce a complete Terraform context for some ancillary functionality
// like "terraform console", "terraform state ...", etc.
//
// This function is guaranteed not to modify the given map, but it may return
// the given map unchanged if no additions are required. If additions are
// required then the result will be a new map containing everything in the
// given map plus additional elements.
func (b *Local) stubUnsetRequiredVariables(existing map[string]backend.UnparsedVariableValue, vcs map[string]*configs.Variable) map[string]backend.UnparsedVariableValue {
	var missing bool // Do we need to add anything?
	for name, vc := range vcs {
		if !vc.Required() {
			continue // We only stub required variables
		}
		if _, exists := existing[name]; !exists {
			missing = true
		}
	}
	if !missing {
		return existing
	}

	// If we get down here then there's at least one variable value to add.
	ret := make(map[string]backend.UnparsedVariableValue, len(vcs))
	for k, v := range existing {
		ret[k] = v
	}
	for name, vc := range vcs {
		if !vc.Required() {
			continue
		}
		if _, exists := existing[name]; !exists {
			ret[name] = unparsedUnknownVariableValue{Name: name, WantType: vc.Type}
		}
	}
	return ret
}

type unparsedInteractiveVariableValue struct {
	Name, RawValue string
}

var _ backend.UnparsedVariableValue = unparsedInteractiveVariableValue{}

func (v unparsedInteractiveVariableValue) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	val, valDiags := mode.Parse(v.Name, v.RawValue)
	diags = diags.Append(valDiags)
	if diags.HasErrors() {
		return nil, diags
	}
	return &terraform.InputValue{
		Value:      val,
		SourceType: terraform.ValueFromInput,
	}, diags
}

type unparsedUnknownVariableValue struct {
	Name     string
	WantType cty.Type
}

var _ backend.UnparsedVariableValue = unparsedUnknownVariableValue{}

func (v unparsedUnknownVariableValue) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
	return &terraform.InputValue{
		Value:      cty.UnknownVal(v.WantType),
		SourceType: terraform.ValueFromInput,
	}, nil
}
