import ChildProcess from 'child_process';
import fs from 'fs';
import path from 'path';

const appFolder = path.resolve(process.execPath, '..');
const rootFolder = path.resolve(appFolder, '..');
const binFolder = path.join(rootFolder, 'bin');
const updateDotExe = path.join(rootFolder, 'Update.exe');

// Spawn a command and invoke the callback when it completes with an error
// and the output from standard out.
function spawn(command, args, callback) {
  let stdout = '';

  let spawnedProcess;
  try {
    spawnedProcess = ChildProcess.spawn(command, args);
  }
  catch (error) {
    // Spawn can throw an error
    process.nextTick(() => {
      if (callback != null) {
        callback(error, stdout);
      }
    });
    return;
  }

  spawnedProcess.stdout.on('data', data => {
    stdout += data;
  });

  let error = null;
  spawnedProcess.on('error', processError => {
    if (error != null) {
      error = processError;
    }
  });
  spawnedProcess.on('close', (code, signal) => {
    if (error != null && code !== 0) {
      error = new Error('Command failed: ' + (signal || code));
    }
    if (error != null) {
      error.code = error.code || code;
      error.stdout = error.stdout || stdout;
    }
    if (callback != null) {
      callback(error, stdout);
    }
  });
}

// Spawn the Update.exe with the given arguments and invoke the callback when
// the command completes.
export function spawnUpdate(args, callback) {
  spawn(updateDotExe, args, callback);
}

// Is the Update.exe installed?
export function existsSync() {
  return fs.existsSync(updateDotExe);
}

// Restart App.
export function restart(app, newVersion) {
  app.once('will-quit', function() {
    let execPath = process.execPath.replace(app.getVersion(), newVersion);
    spawn(execPath, process.execArgv);
  });
  app.quit();
}
