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

package arguments

import (
	"fmt"

	"github.com/hashicorp/terraform/internal/plans"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

// Apply represents the command-line arguments for the apply command.
type Apply struct {
	// State, Operation, and Vars are the common extended flags
	State     *State
	Operation *Operation
	Vars      *Vars

	// AutoApprove skips the manual verification step for the apply operation.
	AutoApprove bool

	// InputEnabled is used to disable interactive input for unspecified
	// variable and backend config values. Default is true.
	InputEnabled bool

	// PlanPath contains an optional path to a stored plan file
	PlanPath string

	// ViewType specifies which output format to use
	ViewType ViewType
}

// ParseApply processes CLI arguments, returning an Apply value and errors.
// If errors are encountered, an Apply value is still returned representing
// the best effort interpretation of the arguments.
func ParseApply(args []string) (*Apply, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	apply := &Apply{
		State:     &State{},
		Operation: &Operation{},
		Vars:      &Vars{},
	}

	cmdFlags := extendedFlagSet("apply", apply.State, apply.Operation, apply.Vars)
	cmdFlags.BoolVar(&apply.AutoApprove, "auto-approve", false, "auto-approve")
	cmdFlags.BoolVar(&apply.InputEnabled, "input", true, "input")

	var json bool
	cmdFlags.BoolVar(&json, "json", false, "json")

	if err := cmdFlags.Parse(args); err != nil {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Failed to parse command-line flags",
			err.Error(),
		))
	}

	args = cmdFlags.Args()
	if len(args) > 0 {
		apply.PlanPath = args[0]
		args = args[1:]
	}

	if len(args) > 0 {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Too many command line arguments",
			"Expected at most one positional argument.",
		))
	}

	// JSON view currently does not support input, so we disable it here.
	if json {
		apply.InputEnabled = false
	}

	// JSON view cannot confirm apply, so we require either a plan file or
	// auto-approve to be specified. We intentionally fail here rather than
	// override auto-approve, which would be dangerous.
	if json && apply.PlanPath == "" && !apply.AutoApprove {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Plan file or auto-approve required",
			"Terraform cannot ask for interactive approval when -json is set. You can either apply a saved plan file, or enable the -auto-approve option.",
		))
	}

	diags = diags.Append(apply.Operation.Parse())

	switch {
	case json:
		apply.ViewType = ViewJSON
	default:
		apply.ViewType = ViewHuman
	}

	return apply, diags
}

// ParseApplyDestroy is a special case of ParseApply that deals with the
// "terraform destroy" command, which is effectively an alias for
// "terraform apply -destroy".
func ParseApplyDestroy(args []string) (*Apply, tfdiags.Diagnostics) {
	apply, diags := ParseApply(args)

	// So far ParseApply was using the command line options like -destroy
	// and -refresh-only to determine the plan mode. For "terraform destroy"
	// we expect neither of those arguments to be set, and so the plan mode
	// should currently be set to NormalMode, which we'll replace with
	// DestroyMode here. If it's already set to something else then that
	// suggests incorrect usage.
	switch apply.Operation.PlanMode {
	case plans.NormalMode:
		// This indicates that the user didn't specify any mode options at
		// all, which is correct, although we know from the command that
		// they actually intended to use DestroyMode here.
		apply.Operation.PlanMode = plans.DestroyMode
	case plans.DestroyMode:
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Invalid mode option",
			"The -destroy option is not valid for \"terraform destroy\", because this command always runs in destroy mode.",
		))
	case plans.RefreshOnlyMode:
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Invalid mode option",
			"The -refresh-only option is not valid for \"terraform destroy\".",
		))
	default:
		// This is a non-ideal error message for if we forget to handle a
		// newly-handled plan mode in Operation.Parse. Ideally they should all
		// have cases above so we can produce better error messages.
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			"Invalid mode option",
			fmt.Sprintf("The \"terraform destroy\" command doesn't support %s.", apply.Operation.PlanMode),
		))
	}

	// NOTE: It's also invalid to have apply.PlanPath set in this codepath,
	// but we don't check that in here because we'll return a different error
	// message depending on whether the given path seems to refer to a saved
	// plan file or to a configuration directory. The apply command
	// implementation itself therefore handles this situation.

	return apply, diags
}
