package cmds

import (
	"agent/commons/debug"
	"agent/commons/utils"
	"agent/defines/dcmds"
	"agent/defines/derrs"
	"agent/defines/devent/daction"
	"agent/defines/devent/dcategory"
	"context"
	"os"
	"path/filepath"
)

type ItemMoveCmd struct {
	dcmds.UserToAgentCmd
}

func (c *ItemMoveCmd) Category() []Category {
	return []Category{dcategory.Agent, dcategory.Rfs, dcategory.Item}
}

func (c *ItemMoveCmd) Action() Action {
	return daction.Move
}

func (c *ItemMoveCmd) Execute(ctx context.Context, eventIn IEvent) (eventOut IEvent, err error) {
	debug.Log("ItemMoveCmd")

	meta := eventIn.Meta()

	fromPath, ok := meta["from_path"].(string)
	if !ok {
		return nil, derrs.NewIncorrectParamsError("from_path not found")
	}
	fromPath = normalizePath(fromPath)

	toPath, ok := meta["to_path"].(string)
	if !ok {
		return nil, derrs.NewIncorrectParamsError("to_path not found")
	}
	toPath = normalizePath(toPath)

	defer func() {
		if err != nil {
			debug.Logf("ItemMove.Error(%s, %s): %s\n", fromPath, toPath, err)
			return
		}
	}()

	var fromDir string
	if utils.FileIsExist(fromPath) {
		fromDir = filepath.Dir(fromPath)
	} else if utils.DirIsExist(fromPath) {
		fromDir = filepath.Dir(fromPath)
	} else {
		return nil, derrs.NewIncorrectParamsError("from_path does not exist")
	}

	if fromPath != toPath {
		if !utils.DirIsExist(filepath.Dir(toPath)) {
			return nil, derrs.NewIncorrectParamsError("to_path directory does not exist")
		}
		// Если toPath это существующая директория, то элемент будет перемещен внуть папки
		if utils.DirIsExist(toPath) {
			toPath = filepath.Join(toPath, utils.FileNameFull(fromPath))
		}
		if utils.FileIsExist(fromPath) {
			debug.Logf("MoveFile: %s to %s\n\n", fromPath, toPath)
			err = os.Rename(fromPath, toPath)
		} else if utils.DirIsExist(fromPath) {
			debug.Logf("MoveFolder: %s to %s\n\n", fromPath, toPath)
			err = os.Rename(fromPath, toPath)
		} else {
			err = derrs.NewIncorrectParamsError("from_path does not exist")
		}
		if err != nil {
			return nil, err
		}
	}

	var dirs []string
	if len(fromDir) > 0 {
		dirs = append(dirs, fromDir)
	}
	if toDir := filepath.Dir(toPath); len(toDir) > 0 && fromDir != toDir {
		dirs = append(dirs, toDir)
	}

	if len(dirs) == 0 {
		return nil, derrs.NewIncorrectParamsError("no directories to list")
	}

	return listFoldersToResultEvent(eventIn, dirs...)
}
