
var versions = require('./versions');
var schema = require('./lib/schema');

exports.migrate = function (targetVersion, callback) {
  // Parameters:
  //   targetVersion
  //     Optional version integer to migrate to. If not specified,
  //     the target version is fetched from the package.json.
  //   callback
  //     function (err)

  // Get desired version
  if (typeof targetVersion === 'function') {
    callback = targetVersion;
    targetVersion = schema.getDesiredVersion();
  }

  if (typeof targetVersion !== 'number') {
    throw new Error('targetVersion must be a number');
  }

  if (typeof callback !== 'function') {
    throw new Error('callback must be a function');
  }

  console.log('##### Migration #####');
  console.log('');

  // Get current version.
  console.log('Checking versions...');
  schema.getVersion(function (err, currentVersion) {
    if (err) {
      return callback(err);
    }  // else

    console.log('  Current DB schema version:', currentVersion);
    console.log('  Desired DB schema version:', targetVersion);

    if (currentVersion < targetVersion) {
      console.log();
      console.log('#### Migrating from', currentVersion, 'to',
                  targetVersion, '####');

      versions.run(currentVersion, targetVersion, function (err2) {

        if (err2) {
          console.log();
          console.log('##### Migration FAILED #####');

          return callback(err2);
        }  // else

        console.log();
        console.log('##### Migration SUCCESS #####');

        return callback();
      });
    } else {
      console.log();
      console.log('DB schema versions are already met.');
      console.log();
      console.log('##### Migration SUCCESS #####');

      return callback();
    }
  });
};


var versions = require('./versions');
var schema = require('./lib/schema');
var backups = require('./backups');

var BACKUP_DIR = backups.getBackupDirPathForName('migration');

var cleanup = function (callback) {
  console.log('Discarding the backup files...');
  backups.discardFrom(BACKUP_DIR, function (errdi) {
    if (errdi) {
      console.log('FAILED to discard backup files.');
      console.error(errdi);
    } else {
      console.log('Backup files discarded successfully.');
    }
    return callback();
  });
};

exports.migrate = function (targetVersion, callback) {
  // Parameters:
  //   targetVersion
  //     Optional version integer to migrate to. If not specified,
  //     the target version is fetched from the package.json.
  //   callback
  //     function (err)

  // Get desired version
  if (typeof targetVersion === 'function') {
    callback = targetVersion;
    targetVersion = schema.getDesiredVersion();
  }

  if (typeof targetVersion !== 'number') {
    throw new Error('targetVersion must be a number');
  }

  if (typeof callback !== 'function') {
    throw new Error('callback must be a function');
  }

  console.log('##### Migration #####');
  console.log('');

  // Get current version.
  console.log('Checking versions...');
  schema.getVersion(function (err, currentVersion) {
    if (err) {
      return callback(err);
    }  // else

    console.log('  Current DB schema version:', currentVersion);
    console.log('  Desired DB schema version:', targetVersion);

    if (currentVersion < targetVersion) {
      console.log();
      console.log('#### Backing up the database ####');
      console.log('If migration fails, the original db state is restored.');

      backups.backupTo(BACKUP_DIR, function (errb) {
        if (errb) {
          console.log();
          console.log('FAILED to back up the database. Stopping...');
          return callback(errb);
        }

        console.log('Database stored to', BACKUP_DIR);
        console.log('Ready for migration.');
        console.log();
        console.log('#### Migrating from', currentVersion, 'to',
                    targetVersion, '####');

        versions.run(currentVersion, targetVersion, function (err2) {
          if (err2) {
            console.log();
            console.log('##### Migration FAILED #####');

            console.log('##### Restoring the database #####');
            backups.restoreFrom(BACKUP_DIR, function (erres) {
              if (erres) {
                console.log('FAILED to restore the backup.');
                console.log('Please inspect the backup files.');
                console.error(erres);
                return callback(err2);
              } // else

              console.log('Database restored successfully.');

              cleanup(function () {
                return callback(err2); // propagate the original error
              });
            });
            return;
          } // else

          console.log();
          console.log('##### Migration SUCCESS #####');

          cleanup(function () {
            return callback();
          });
        });
      });
    } else {
      console.log();
      console.log('DB schema versions are already met.');
      console.log();
      console.log('##### Migration SUCCESS #####');

      return callback();
    }
  });
};

Backup database before migration and fall back if needed