#!/usr/bin/env node
'use strict';

/* eslint-disable no-console */
const spawnSync = require( 'child_process').spawnSync;
const fs = require('fs');
const temp = require('temp');
const { blue, green, red, gray, yellow } = require('chalk');

const path = require('path');
const glob = require('glob');
const cli = 'https://github.com/angular/angular-cli.git';
const cliBuilds = 'https://github.com/angular/cli-builds.git';
const ngToolsWebpackBuilds = 'https://github.com/angular/ngtools-webpack-builds.git';


class Executor {
  constructor(cwd) { this._cwd = cwd; }

  execute(command, ...args) {
    args = args.filter(x => x !== undefined);
    console.log(blue(`Running \`${command} ${args.map(x => `"${x}"`).join(' ')}\`...`));
    console.log(blue(`CWD: ${this._cwd}`));

    const runCommand = spawnSync(command, args, { cwd: this._cwd });
    if (runCommand.status === 0) {
      console.log(gray(runCommand.stdout.toString()));
      return runCommand.stdout.toString();
    } else {
      throw new Error(
        `Command returned status ${runCommand.status}. Details:\n${runCommand.stderr}`);
    }
  }

  git(...args) { return this.execute('git', ...args); }
  npm(...args) { return this.execute('npm', ...args); }
  rm(...args) { return this.execute('rm', ...args); }

  glob(pattern, options) {
    return glob.sync(pattern, Object.assign({}, options || {}, { cwd: this._cwd }));
  }

  cp(root, destRoot) {
    function mkdirp(p) {
      if (fs.existsSync(p)) {
        return;
      }
      mkdirp(path.dirname(p));
      fs.mkdirSync(p);
    }

    this.glob(path.join(root, '**/*'), { nodir: true })
      .forEach(name => {
        const src = name;
        const dest = path.join(destRoot, src.substr(root.length));

        mkdirp(path.dirname(dest));
        fs.writeFileSync(dest, fs.readFileSync(src));
      });
  }

  read(p) {
    return fs.readFileSync(path.join(this._cwd, p), 'utf-8');
  }
  write(p, content) {
    fs.writeFileSync(path.join(this._cwd, p), content);
  }

  updateVersion(hash) {
    const packageJson = JSON.parse(this.read('package.json'));
    packageJson.version = `${packageJson.version}-${hash.substr(1, 7)}`;
    this.write('package.json', JSON.stringify(packageJson, null, 2));
  }

  updateDependencies(hash) {
    const packageJson = JSON.parse(this.read('package.json'));
    packageJson.dependencies['@ngtools/webpack'] = ngToolsWebpackBuilds + '#' + hash;
    this.write('package.json', JSON.stringify(packageJson, null, 2));
  }
}


function main() {
  const cliPath = process.cwd();
  const cliExec = new Executor(cliPath);
  const tempRoot = temp.mkdirSync('angular-cli-builds');
  const tempExec = new Executor(tempRoot);

  console.log(green(`Cloning builds repos...\n`));
  tempExec.git('clone', cliBuilds);
  tempExec.git('clone', ngToolsWebpackBuilds);

  console.log(green('Building...'));

  const cliBuildsRoot = path.join(tempRoot, 'cli-builds');
  const cliBuildsExec = new Executor(cliBuildsRoot);
  const ngToolsWebpackBuildsRoot = path.join(tempRoot, 'ngtools-webpack-builds');
  const ngToolsWebpackBuildsExec = new Executor(ngToolsWebpackBuildsRoot);

  cliExec.npm('run', 'build');

  const message = cliExec.git('log', '--format=%h %s', '-n', '1');
  const hash = message.split(' ')[0];

  console.log(green('Copying ng-tools-webpack-builds dist'));
  ngToolsWebpackBuildsExec.git('checkout', '-B', process.env['TRAVIS_BRANCH']);
  ngToolsWebpackBuildsExec.rm('-rf', ...ngToolsWebpackBuildsExec.glob('*'));
  cliExec.cp('dist/@ngtools/webpack', ngToolsWebpackBuildsRoot);
  console.log(green('Updating package.json version'));
  ngToolsWebpackBuildsExec.updateVersion(hash);
  ngToolsWebpackBuildsExec.git('add', '-A');
  ngToolsWebpackBuildsExec.git('commit', '-m', message);
  ngToolsWebpackBuildsExec.git('tag', hash);

  ngToolsWebpackBuildsExec.git('config', 'credential.helper', 'store --file=.git/credentials');
  ngToolsWebpackBuildsExec.write('.git/credentials',
      `https://${process.env['GITHUB_ACCESS_TOKEN']}@github.com`);


  console.log(green('Copying cli-builds dist'));
  cliBuildsExec.git('checkout', '-B', process.env['TRAVIS_BRANCH']);
  cliBuildsExec.rm('-rf', ...cliBuildsExec.glob('*'));
  cliExec.cp('dist/@angular/cli', cliBuildsRoot);

  console.log(green('Updating package.json version'));
  cliBuildsExec.updateVersion(hash);
  cliBuildsExec.updateDependencies(hash);

  cliBuildsExec.git('add', '-A');
  cliBuildsExec.git('commit', '-m', message);
  cliBuildsExec.git('tag', hash);

  cliBuildsExec.git('config', 'credential.helper', 'store --file=.git/credentials');
  cliBuildsExec.write('.git/credentials',
    `https://${process.env['GITHUB_ACCESS_TOKEN']}@github.com`);

  console.log(green('Done. Pushing...'));
  ngToolsWebpackBuildsExec.git('push', '-f');
  ngToolsWebpackBuildsExec.git('push', '--tags');
  cliBuildsExec.git('push', '-f');
  cliBuildsExec.git('push', '--tags');
}

main();

@@ -196,25 +196,12 @@
 en, 
-red, gray, yellow
+gray
  %7D =
@@ -284,66 +284,8 @@
 ');%0A
-const cli = 'https://github.com/angular/angular-cli.git';%0A
 cons
@@ -468,16 +468,20 @@
 r(cwd) %7B
+%0A   
  this._c
@@ -489,16 +489,18 @@
 d = cwd;
+%0A 
  %7D%0A%0A  ex
@@ -1051,32 +1051,36 @@
   git(...args) %7B
+%0A   
  return this.exe
@@ -1096,24 +1096,26 @@
 ', ...args);
+%0A 
  %7D%0A  npm(...
@@ -1113,32 +1113,36 @@
   npm(...args) %7B
+%0A   
  return this.exe
@@ -1162,16 +1162,18 @@
 ..args);
+%0A 
  %7D%0A  rm(
@@ -1182,16 +1182,20 @@
 .args) %7B
+%0A   
  return 
@@ -1222,16 +1222,18 @@
 ..args);
+%0A 
  %7D%0A%0A  gl
@@ -2096,21 +2096,8 @@
 hash
-.substr(1, 7)
 %7D%60;%0A
@@ -2640,17 +2640,17 @@
 g(green(
-%60
+'
 Cloning 
@@ -2666,17 +2666,17 @@
 pos...%5Cn
-%60
+'
 ));%0A  te

fix deploy script condition (take 11)