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

package command

import (
	"fmt"
	"strings"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/backend"
	"github.com/hashicorp/terraform/internal/command/arguments"
	"github.com/hashicorp/terraform/internal/command/clistate"
	"github.com/hashicorp/terraform/internal/command/views"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/terraform"
	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/mitchellh/cli"
)

// StateMvCommand is a Command implementation that shows a single resource.
type StateMvCommand struct {
	StateMeta
}

func (c *StateMvCommand) Run(args []string) int {
	args = c.Meta.process(args)
	// We create two metas to track the two states
	var backupPathOut, statePathOut string

	var dryRun bool
	cmdFlags := c.Meta.ignoreRemoteVersionFlagSet("state mv")
	cmdFlags.BoolVar(&dryRun, "dry-run", false, "dry run")
	cmdFlags.StringVar(&c.backupPath, "backup", "-", "backup")
	cmdFlags.StringVar(&backupPathOut, "backup-out", "-", "backup")
	cmdFlags.BoolVar(&c.Meta.stateLock, "lock", true, "lock states")
	cmdFlags.DurationVar(&c.Meta.stateLockTimeout, "lock-timeout", 0, "lock timeout")
	cmdFlags.StringVar(&c.statePath, "state", "", "path")
	cmdFlags.StringVar(&statePathOut, "state-out", "", "path")
	if err := cmdFlags.Parse(args); err != nil {
		c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
		return 1
	}
	args = cmdFlags.Args()
	if len(args) != 2 {
		c.Ui.Error("Exactly two arguments expected.\n")
		return cli.RunResultHelp
	}

	if diags := c.Meta.checkRequiredVersion(); diags != nil {
		c.showDiagnostics(diags)
		return 1
	}

	// If backup or backup-out options are set
	// and the state option is not set, make sure
	// the backend is local
	backupOptionSetWithoutStateOption := c.backupPath != "-" && c.statePath == ""
	backupOutOptionSetWithoutStateOption := backupPathOut != "-" && c.statePath == ""

	var setLegacyLocalBackendOptions []string
	if backupOptionSetWithoutStateOption {
		setLegacyLocalBackendOptions = append(setLegacyLocalBackendOptions, "-backup")
	}
	if backupOutOptionSetWithoutStateOption {
		setLegacyLocalBackendOptions = append(setLegacyLocalBackendOptions, "-backup-out")
	}

	if len(setLegacyLocalBackendOptions) > 0 {
		currentBackend, diags := c.backendFromConfig(&BackendOpts{})
		if diags.HasErrors() {
			c.showDiagnostics(diags)
			return 1
		}

		// If currentBackend is nil and diags didn't have errors,
		// this means we have an implicit local backend
		_, isLocalBackend := currentBackend.(backend.Local)
		if currentBackend != nil && !isLocalBackend {
			diags = diags.Append(
				tfdiags.Sourceless(
					tfdiags.Error,
					fmt.Sprintf("Invalid command line options: %s", strings.Join(setLegacyLocalBackendOptions[:], ", ")),
					"Command line options -backup and -backup-out are legacy options that operate on a local state file only. You must specify a local state file with the -state option or switch to the local backend.",
				),
			)
			c.showDiagnostics(diags)
			return 1
		}
	}

	// Read the from state
	stateFromMgr, err := c.State()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
		return 1
	}

	if c.stateLock {
		stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
		if diags := stateLocker.Lock(stateFromMgr, "state-mv"); diags.HasErrors() {
			c.showDiagnostics(diags)
			return 1
		}
		defer func() {
			if diags := stateLocker.Unlock(); diags.HasErrors() {
				c.showDiagnostics(diags)
			}
		}()
	}

	if err := stateFromMgr.RefreshState(); err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to refresh source state: %s", err))
		return 1
	}

	stateFrom := stateFromMgr.State()
	if stateFrom == nil {
		c.Ui.Error(errStateNotFound)
		return 1
	}

	// Read the destination state
	stateToMgr := stateFromMgr
	stateTo := stateFrom

	if statePathOut != "" {
		c.statePath = statePathOut
		c.backupPath = backupPathOut

		stateToMgr, err = c.State()
		if err != nil {
			c.Ui.Error(fmt.Sprintf(errStateLoadingState, err))
			return 1
		}

		if c.stateLock {
			stateLocker := clistate.NewLocker(c.stateLockTimeout, views.NewStateLocker(arguments.ViewHuman, c.View))
			if diags := stateLocker.Lock(stateToMgr, "state-mv"); diags.HasErrors() {
				c.showDiagnostics(diags)
				return 1
			}
			defer func() {
				if diags := stateLocker.Unlock(); diags.HasErrors() {
					c.showDiagnostics(diags)
				}
			}()
		}

		if err := stateToMgr.RefreshState(); err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to refresh destination state: %s", err))
			return 1
		}

		stateTo = stateToMgr.State()
		if stateTo == nil {
			stateTo = states.NewState()
		}
	}

	var diags tfdiags.Diagnostics
	sourceAddr, moreDiags := c.lookupSingleStateObjectAddr(stateFrom, args[0])
	diags = diags.Append(moreDiags)
	destAddr, moreDiags := c.lookupSingleStateObjectAddr(stateFrom, args[1])
	diags = diags.Append(moreDiags)
	if diags.HasErrors() {
		c.showDiagnostics(diags)
		return 1
	}

	prefix := "Move"
	if dryRun {
		prefix = "Would move"
	}

	const msgInvalidSource = "Invalid source address"
	const msgInvalidTarget = "Invalid target address"

	var moved int
	ssFrom := stateFrom.SyncWrapper()
	sourceAddrs := c.sourceObjectAddrs(stateFrom, sourceAddr)
	if len(sourceAddrs) == 0 {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			msgInvalidSource,
			fmt.Sprintf("Cannot move %s: does not match anything in the current state.", sourceAddr),
		))
		c.showDiagnostics(diags)
		return 1
	}
	for _, rawAddrFrom := range sourceAddrs {
		switch addrFrom := rawAddrFrom.(type) {
		case addrs.ModuleInstance:
			search := sourceAddr.(addrs.ModuleInstance)
			addrTo, ok := destAddr.(addrs.ModuleInstance)
			if !ok {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidTarget,
					fmt.Sprintf("Cannot move %s to %s: the target must also be a module.", addrFrom, destAddr),
				))
				c.showDiagnostics(diags)
				return 1
			}

			if len(search) < len(addrFrom) {
				n := make(addrs.ModuleInstance, 0, len(addrTo)+len(addrFrom)-len(search))
				n = append(n, addrTo...)
				n = append(n, addrFrom[len(search):]...)
				addrTo = n
			}

			if stateTo.Module(addrTo) != nil {
				c.Ui.Error(fmt.Sprintf(errStateMv, "destination module already exists"))
				return 1
			}

			ms := ssFrom.Module(addrFrom)
			if ms == nil {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidSource,
					fmt.Sprintf("The current state does not contain %s.", addrFrom),
				))
				c.showDiagnostics(diags)
				return 1
			}

			moved++
			c.Ui.Output(fmt.Sprintf("%s %q to %q", prefix, addrFrom.String(), addrTo.String()))
			if !dryRun {
				ssFrom.RemoveModule(addrFrom)

				// Update the address before adding it to the state.
				ms.Addr = addrTo
				stateTo.Modules[addrTo.String()] = ms
			}

		case addrs.AbsResource:
			addrTo, ok := destAddr.(addrs.AbsResource)
			if !ok {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidTarget,
					fmt.Sprintf("Cannot move %s to %s: the source is a whole resource (not a resource instance) so the target must also be a whole resource.", addrFrom, destAddr),
				))
				c.showDiagnostics(diags)
				return 1
			}
			diags = diags.Append(c.validateResourceMove(addrFrom, addrTo))

			if stateTo.Resource(addrTo) != nil {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidTarget,
					fmt.Sprintf("Cannot move to %s: there is already a resource at that address in the current state.", addrTo),
				))
			}

			rs := ssFrom.Resource(addrFrom)
			if rs == nil {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidSource,
					fmt.Sprintf("The current state does not contain %s.", addrFrom),
				))
			}

			if diags.HasErrors() {
				c.showDiagnostics(diags)
				return 1
			}

			moved++
			c.Ui.Output(fmt.Sprintf("%s %q to %q", prefix, addrFrom.String(), addrTo.String()))
			if !dryRun {
				ssFrom.RemoveResource(addrFrom)

				// Update the address before adding it to the state.
				rs.Addr = addrTo
				stateTo.EnsureModule(addrTo.Module).Resources[addrTo.Resource.String()] = rs
			}

		case addrs.AbsResourceInstance:
			addrTo, ok := destAddr.(addrs.AbsResourceInstance)
			if !ok {
				ra, ok := destAddr.(addrs.AbsResource)
				if !ok {
					diags = diags.Append(tfdiags.Sourceless(
						tfdiags.Error,
						msgInvalidTarget,
						fmt.Sprintf("Cannot move %s to %s: the target must also be a resource instance.", addrFrom, destAddr),
					))
					c.showDiagnostics(diags)
					return 1
				}
				addrTo = ra.Instance(addrs.NoKey)
			}

			diags = diags.Append(c.validateResourceMove(addrFrom.ContainingResource(), addrTo.ContainingResource()))

			if stateTo.Module(addrTo.Module) == nil {
				// moving something to a mew module, so we need to ensure it exists
				stateTo.EnsureModule(addrTo.Module)
			}
			if stateTo.ResourceInstance(addrTo) != nil {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidTarget,
					fmt.Sprintf("Cannot move to %s: there is already a resource instance at that address in the current state.", addrTo),
				))
			}

			is := ssFrom.ResourceInstance(addrFrom)
			if is == nil {
				diags = diags.Append(tfdiags.Sourceless(
					tfdiags.Error,
					msgInvalidSource,
					fmt.Sprintf("The current state does not contain %s.", addrFrom),
				))
			}

			if diags.HasErrors() {
				c.showDiagnostics(diags)
				return 1
			}

			moved++
			c.Ui.Output(fmt.Sprintf("%s %q to %q", prefix, addrFrom.String(), args[1]))
			if !dryRun {
				fromResourceAddr := addrFrom.ContainingResource()
				fromResource := ssFrom.Resource(fromResourceAddr)
				fromProviderAddr := fromResource.ProviderConfig
				ssFrom.ForgetResourceInstanceAll(addrFrom)
				ssFrom.RemoveResourceIfEmpty(fromResourceAddr)

				rs := stateTo.Resource(addrTo.ContainingResource())
				if rs == nil {
					// If we're moving to an address without an index then that
					// suggests the user's intent is to establish both the
					// resource and the instance at the same time (since the
					// address covers both). If there's an index in the
					// target then allow creating the new instance here.
					resourceAddr := addrTo.ContainingResource()
					stateTo.SyncWrapper().SetResourceProvider(
						resourceAddr,
						fromProviderAddr, // in this case, we bring the provider along as if we were moving the whole resource
					)
					rs = stateTo.Resource(resourceAddr)
				}

				rs.Instances[addrTo.Resource.Key] = is
			}
		default:
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				msgInvalidSource,
				fmt.Sprintf("Cannot move %s: Terraform doesn't know how to move this object.", rawAddrFrom),
			))
		}

		// Look for any dependencies that may be effected and
		// remove them to ensure they are recreated in full.
		for _, mod := range stateTo.Modules {
			for _, res := range mod.Resources {
				for _, ins := range res.Instances {
					if ins.Current == nil {
						continue
					}

					for _, dep := range ins.Current.Dependencies {
						// check both directions here, since we may be moving
						// an instance which is in a resource, or a module
						// which can contain a resource.
						if dep.TargetContains(rawAddrFrom) || rawAddrFrom.TargetContains(dep) {
							ins.Current.Dependencies = nil
							break
						}
					}
				}
			}
		}
	}

	if dryRun {
		if moved == 0 {
			c.Ui.Output("Would have moved nothing.")
		}
		return 0 // This is as far as we go in dry-run mode
	}

	b, backendDiags := c.Backend(nil)
	diags = diags.Append(backendDiags)
	if backendDiags.HasErrors() {
		c.showDiagnostics(diags)
		return 1
	}

	// Get schemas, if possible, before writing state
	var schemas *terraform.Schemas
	if isCloudMode(b) {
		var schemaDiags tfdiags.Diagnostics
		schemas, schemaDiags = c.MaybeGetSchemas(stateTo, nil)
		diags = diags.Append(schemaDiags)
	}

	// Write the new state
	if err := stateToMgr.WriteState(stateTo); err != nil {
		c.Ui.Error(fmt.Sprintf(errStateRmPersist, err))
		return 1
	}
	if err := stateToMgr.PersistState(schemas); err != nil {
		c.Ui.Error(fmt.Sprintf(errStateRmPersist, err))
		return 1
	}

	// Write the old state if it is different
	if stateTo != stateFrom {
		if err := stateFromMgr.WriteState(stateFrom); err != nil {
			c.Ui.Error(fmt.Sprintf(errStateRmPersist, err))
			return 1
		}
		if err := stateFromMgr.PersistState(schemas); err != nil {
			c.Ui.Error(fmt.Sprintf(errStateRmPersist, err))
			return 1
		}
	}

	c.showDiagnostics(diags)

	if moved == 0 {
		c.Ui.Output("No matching objects found.")
	} else {
		c.Ui.Output(fmt.Sprintf("Successfully moved %d object(s).", moved))
	}
	return 0
}

// sourceObjectAddrs takes a single source object address and expands it to
// potentially multiple objects that need to be handled within it.
//
// In particular, this handles the case where a module is requested directly:
// if it has any child modules, then they must also be moved. It also resolves
// the ambiguity that an index-less resource address could either be a resource
// address or a resource instance address, by making a decision about which
// is intended based on the current state of the resource in question.
func (c *StateMvCommand) sourceObjectAddrs(state *states.State, matched addrs.Targetable) []addrs.Targetable {
	var ret []addrs.Targetable

	switch addr := matched.(type) {
	case addrs.ModuleInstance:
		for _, mod := range state.Modules {
			if len(mod.Addr) < len(addr) {
				continue // can't possibly be our selection or a child of it
			}
			if !mod.Addr[:len(addr)].Equal(addr) {
				continue
			}
			ret = append(ret, mod.Addr)
		}
	case addrs.AbsResource:
		// If this refers to a resource without "count" or "for_each" set then
		// we'll assume the user intended it to be a resource instance
		// address instead, to allow for requests like this:
		//   terraform state mv aws_instance.foo aws_instance.bar[1]
		// That wouldn't be allowed if aws_instance.foo had multiple instances
		// since we can't move multiple instances into one.
		if rs := state.Resource(addr); rs != nil {
			if _, ok := rs.Instances[addrs.NoKey]; ok {
				ret = append(ret, addr.Instance(addrs.NoKey))
			} else {
				ret = append(ret, addr)
			}
		}
	default:
		ret = append(ret, matched)
	}

	return ret
}

func (c *StateMvCommand) validateResourceMove(addrFrom, addrTo addrs.AbsResource) tfdiags.Diagnostics {
	const msgInvalidRequest = "Invalid state move request"

	var diags tfdiags.Diagnostics
	if addrFrom.Resource.Mode != addrTo.Resource.Mode {
		switch addrFrom.Resource.Mode {
		case addrs.ManagedResourceMode:
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				msgInvalidRequest,
				fmt.Sprintf("Cannot move %s to %s: a managed resource can be moved only to another managed resource address.", addrFrom, addrTo),
			))
		case addrs.DataResourceMode:
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				msgInvalidRequest,
				fmt.Sprintf("Cannot move %s to %s: a data resource can be moved only to another data resource address.", addrFrom, addrTo),
			))
		default:
			// In case a new mode is added in future, this unhelpful error is better than nothing.
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				msgInvalidRequest,
				fmt.Sprintf("Cannot move %s to %s: cannot change resource mode.", addrFrom, addrTo),
			))
		}
	}
	if addrFrom.Resource.Type != addrTo.Resource.Type {
		diags = diags.Append(tfdiags.Sourceless(
			tfdiags.Error,
			msgInvalidRequest,
			fmt.Sprintf("Cannot move %s to %s: resource types don't match.", addrFrom, addrTo),
		))
	}
	return diags
}

func (c *StateMvCommand) Help() string {
	helpText := `
Usage: terraform [global options] state mv [options] SOURCE DESTINATION

 This command will move an item matched by the address given to the
 destination address. This command can also move to a destination address
 in a completely different state file.

 This can be used for simple resource renaming, moving items to and from
 a module, moving entire modules, and more. And because this command can also
 move data to a completely new state, it can also be used for refactoring
 one configuration into multiple separately managed Terraform configurations.

 This command will output a backup copy of the state prior to saving any
 changes. The backup cannot be disabled. Due to the destructive nature
 of this command, backups are required.

 If you're moving an item to a different state file, a backup will be created
 for each state file.

Options:

  -dry-run                If set, prints out what would've been moved but doesn't
                          actually move anything.

  -lock=false             Don't hold a state lock during the operation. This is
                          dangerous if others might concurrently run commands
                          against the same workspace.

  -lock-timeout=0s        Duration to retry a state lock.

  -ignore-remote-version  A rare option used for the remote backend only. See
                          the remote backend documentation for more information.

  -state, state-out, and -backup are legacy options supported for the local
  backend only. For more information, see the local backend's documentation.

`
	return strings.TrimSpace(helpText)
}

func (c *StateMvCommand) Synopsis() string {
	return "Move an item in the state"
}

const errStateMv = `Error moving state: %s

Please ensure your addresses and state paths are valid. No
state was persisted. Your existing states are untouched.`
