'use strict';

require('../fs/index.js');
var Path = require('path');
var index$1 = require('../copy/index.js');
var index$2 = require('../remove/index.js');
var index$3 = require('../mkdirs/index.js');
var index$4 = require('../path-exists/index.js');
var stat$1 = require('../util/stat.js');
var index = require('../../../../_virtual/index20.js');

const fs = index.__exports;
const path = Path;
const { copy } = index$1.copy;
const { remove } = index$2.remove_1;
const { mkdirp } = index$3.mkdirs;
const { pathExists } = index$4.pathExists_1;
const stat = stat$1.stat;

async function move (src, dest, opts = {}) {
  const overwrite = opts.overwrite || opts.clobber || false;

  const { srcStat, isChangingCase = false } = await stat.checkPaths(src, dest, 'move', opts);

  await stat.checkParentPaths(src, srcStat, dest, 'move');

  // If the parent of dest is not root, make sure it exists before proceeding
  const destParent = path.dirname(dest);
  const parsedParentPath = path.parse(destParent);
  if (parsedParentPath.root !== destParent) {
    await mkdirp(destParent);
  }

  return doRename(src, dest, overwrite, isChangingCase)
}

async function doRename (src, dest, overwrite, isChangingCase) {
  if (!isChangingCase) {
    if (overwrite) {
      await remove(dest);
    } else if (await pathExists(dest)) {
      throw new Error('dest already exists.')
    }
  }

  try {
    // Try w/ rename first, and try copy + remove if EXDEV
    await fs.rename(src, dest);
  } catch (err) {
    if (err.code !== 'EXDEV') {
      throw err
    }
    await moveAcrossDevice(src, dest, overwrite);
  }
}

async function moveAcrossDevice (src, dest, overwrite) {
  const opts = {
    overwrite,
    errorOnExist: true,
    preserveTimestamps: true
  };

  await copy(src, dest, opts);
  return remove(src)
}

var move_1 = move;

exports.move_1 = move_1;
