import {
  flatMap,
  isEqual
} from 'lodash';
import axios from 'axios';
import boxen from 'boxen';
import chalk from 'chalk';
import debug from 'debug';
import pkg from '../package.json';

const log = debug('mup:updates');
const SKIP_CHECK_UPDATE = process.env.MUP_SKIP_UPDATE_CHECK === 'true';

function parseVersion(version) {
  return flatMap(version.split('.'), n => n.split('-beta').map(Number));
}

function newerStable(local, remote) {
  for (let i = 0; i < 3; i++) {
    for (let sameIndex = 0; sameIndex < i; sameIndex += 1) {
      if (local[sameIndex] !== remote[sameIndex]) {
        return false;
      }
    }

    if (local[i] < remote[i]) {
      return true;
    }
  }

  return false;
}

function compareVersions(local, remote, next) {
  const beta = local.length > 3;
  let isStable = true;
  let available = newerStable(local, remote);

  if (beta && !available) {
    // check if stable version for beta is available
    available = isEqual(remote, local.slice(0, 3));
  }

  if (beta && !available) {
    // check if newer beta is available
    available = next[3] > local[3];
    isStable = false;
  }

  return {
    available,
    isStable
  };
}

function showUpdateOnExit(version, isStable) {
  const command = isStable ? 'npm i -g mup' : 'npm i -g mup@next';
  let text = `update available ${pkg.version} => ${version}`;

  text += `\nTo update, run ${chalk.green(command)}`;

  process.on('exit', () => {
    console.log(
      boxen(text, {
        padding: 1,
        margin: 1,
        align: 'center',
        borderColor: 'yellow'
      })
    );
  });
}

export default function() {
  log('checking for updates');

    if (SKIP_CHECK_UPDATE) {
      log('skipping update check');

    return;
    }


  return axios.get(`https://registry.npmjs.org/-/package/${pkg.name}/dist-tags`)
    .then(({ data }) => {
      const npmVersion = data.latest;
      const nextVersion = data.next;

      const local = parseVersion(pkg.version);
      const remote = parseVersion(data.latest);
      const next = parseVersion(data.next);

      const {
        available,
        isStable
      } = compareVersions(local, remote, next);

      log('finished update check');
      if (available) {
        showUpdateOnExit(isStable ? npmVersion : nextVersion, isStable);
      }
    }).catch(() => {
      // It is okay if this fails
  });
}

@@ -365,16 +365,20 @@
 '), n =%3E
+%0A   
  n.split
@@ -387,16 +387,54 @@
 -beta').
+filter(segment =%3E segment.length %3E 0).
 map(Numb
@@ -436,16 +436,19 @@
 (Number)
+%0A  
 );%0A%7D%0A%0Afu
@@ -1690,18 +1690,16 @@
 tes');%0A%0A
-  
   if (SK
@@ -1713,26 +1713,24 @@
 K_UPDATE) %7B%0A
-  
     log('ski
@@ -1764,18 +1764,16 @@
 return;%0A
-  
   %7D%0A%0A%0A  
@@ -2387,16 +2387,18 @@
 s fails%0A
+  
   %7D);%0A%7D%0A

Fix comparing beta versions