const {exec} = require('child_process');
const path = require('path');
const url = require('url');
const git = require('simple-git')();
const axios = require('axios');

if (!process.env.GITHUB_TOKEN) {
  throw new Error('GITHUB_TOKEN must be defined in environment');
}

if (!process.env.NOW_TOKEN) {
  throw new Error('NOW_TOKEN must be defined in environment');
}

const NOW = `${path.resolve('./node_modules/now/build/bin/now')} --token ${process.env.NOW_TOKEN}`;
const githubApi = axios.create({
  headers: {
    'Authorization': `token ${process.env.GITHUB_TOKEN}`
  }
});

function stage(cwd, {alias}) {
  return new Promise((resolve, reject) => {
    const nowProc = exec(NOW, {cwd});
    nowProc.stderr.on('data', (error) => reject(new Error(error)));
    nowProc.stdout.on('data', (url) => {
      if (!url) return;
      console.log(`> Aliasing ${url}`);
      const aliasProc = exec(`${NOW} alias set ${url} ${alias}`, {cwd});
      aliasProc.on('data', (error) => reject(new Error(error)));
      aliasProc.on('close', (code) => {
        console.log(`> Alias ready ${alias}`);
        resolve(alias);
      });
    });
  });
}

function sync(cloneUrl, localDirectory, {ref, checkout}) {
  // TODO: Avoid multiple request working on the same localDirectory
  return new Promise((resolve) => {
    git.clone(cloneUrl, localDirectory, [ // TODO: Silence the noise
      '--depth=1',
      `--branch=${ref}`
    ], () => {
      console.log(`> Checking out ${ref}#${checkout}...`);
      git.cwd(localDirectory)
        .fetch('origin', ref)
        .checkout(checkout)
        .then(resolve);
    });
  });
}

function github(data) {
  if (!['opened', 'synchronize'].includes(data.action)) return {success: false};

  const {repository, pull_request} = data;
  const {ref, sha} = pull_request.head;

  return {
    ref,
    sha,
    success: true,
    name: repository.full_name,
    alias: `https://${repository.name.replace(/[^A-Z0-9]/ig, '-')}-${ref}.now.sh`,
    cloneUrl: url.format(Object.assign(
      url.parse(repository.clone_url),
      {auth: process.env.GITHUB_TOKEN}
    )),
    setStatus: (state, description, targetUrl) => {
      console.log(`> Setting GitHub status to "${state}"...`);
      return githubApi.post(pull_request.statuses_url, {
        state: state,
        target_url: targetUrl,
        description: description,
        context: 'ci/stage-ci'
      });
    }
  };
}

module.exports = {
  stage,
  sync,
  github
};

@@ -370,17 +370,45 @@
 nst 
-NOW = %60$%7B
+now = (cmd='') =%3E %7B%0A  const nowBin = 
 path
@@ -451,16 +451,43 @@
 in/now')
+;%0A  return %60$%7BnowBin%7D $%7Bcmd
 %7D --toke
@@ -515,16 +515,20 @@
 OKEN%7D%60;%0A
+%7D;%0A%0A
 const gi
@@ -731,19 +731,21 @@
  = exec(
-NOW
+now()
 , %7Bcwd%7D)
@@ -952,16 +952,13 @@
 xec(
-%60$%7BNOW%7D 
+now(%60
 alia
@@ -979,16 +979,17 @@
 %7Balias%7D%60
+)
 , %7Bcwd%7D)

Move --token to the end of now commands