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/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
	}

	// Write the new state
	if err := stateToMgr.WriteState(stateTo); err != nil {
		c.Ui.Error(fmt.Sprintf(errStateRmPersist, err))
		return 1
	}
	if err := stateToMgr.PersistState(); 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(); 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.`
