const inquirer = require('inquirer')
const semver = require('semver')
const shell = require('shelljs')

shell.set('-e')

if (!shell.which('git')) {
  shell.echo('Sorry, this script requires git')
  shell.exit(1)
}

if (!shell.which('npm')) {
  shell.echo('Sorry, this script requires npm')
  shell.exit(1)
}

let tag
let branch = exec('git symbolic-ref --short HEAD')
const latest = exec('npm view vuetify version')
let latestGit = exec('git describe --abbrev=0 --tags')

shell.echo(`
Current branch is ${branch}
Last git version (from the current location) was ${latestGit}
Latest npm version is ${latest}
`)

promptForVersion()
  .then(verifyBranch)
  .then(confirmVersion)
  .then(version => {
    lint()
    release(version)
    afterRelease()
  })

//============================ FUNCTIONS =============================//

function exec (command) {
  const result = shell.exec(command, { silent: true })
  if (result.code) {
    shell.echo('')
    console.error(result.stdout.trim())
    shell.exit(1)
  }
  return result.stdout.trim()
}

function createVersionOption (name) {
  const prerelease = (semver.prerelease(latestGit) || [])[0]
  const version = semver.inc(latestGit, name.toLowerCase(), false, prerelease || 'beta')
  return {
    name: `${name} (${version})`,
    value: version,
    short: version
  }
}

function promptForVersion () {
  return inquirer.prompt({
    type: 'list',
    name: 'version',
    message: 'Select new version:',
    choices: [
      createVersionOption('Major'),
      createVersionOption('Minor'),
      createVersionOption('Patch'),
      createVersionOption('Prerelease'),
      createVersionOption('Premajor'),
      createVersionOption('Preminor'),
      createVersionOption('Prepatch'),
      {
        name: 'Other',
        value: 'other'
      }
    ],
    default: () => (
      semver.prerelease(latestGit) == null
        ? createVersionOption('Patch').value
        : createVersionOption('Prerelease').value
    ),
    pageSize: 8
  }).then(({ version }) => {
    if (version === 'other') {
      return inquirer.prompt({
        type: 'input',
        name: 'version',
        message: 'Enter new version:',
        validate: val => !!semver.valid(val) || `'${val}' is not a valid version number`,
        filter: val => semver(val).version
      }).then(({ version }) => version)
    }
    return version
  })
}

function verifyBranch (version) {
  tag = semver.prerelease(version) == null ? 'latest' : 'next'

  if (tag === 'latest' && branch !== 'master') {
    shell.echo('\nReleasing on a branch other than \'master\'')
    shell.echo('This may have unintended side-effects')
    return inquirer.prompt({
      type: 'confirm',
      name: 'yes',
      message: 'Do you want to continue?',
      default: false
    }).then(({ yes }) => yes ? version : shell.exit(1))
  }
  return Promise.resolve(version)
}

function confirmVersion (version) {
  shell.echo(`Releasing ${version} on ${branch}`)
  shell.echo(`Tag: ${tag}`)
  return inquirer.prompt({
    type: 'confirm',
    name: 'yes',
    message: 'Are you sure?',
    default: true
  }).then(({ yes }) => yes ? version : shell.exit(1))
}

function lint () {
  shell.exec('npm run lint')
  shell.exec('npm run test')
}

function release (version) {
  process.env.npm_config_commit_hooks = 'false'

  shell.exec(`npm version ${version} --message "[release] ${version}"`)
  if (exec(`git config branch.${branch}.remote`)) {
    shell.exec(`git push --no-verify --follow-tags`)
  } else {
    const remote = exec(`git config branch.master.remote`)
    shell.exec(`git push --no-verify --follow-tags -u ${remote}`)
  }
}

function afterRelease () {
  if (branch.match(/release\/.*/)) {
    const previousBranch = branch
    shell.exec('git checkout master')
    branch = 'master'
    shell.exec('git pull --ff-only')
    shell.exec(`git merge ${previousBranch}`)
    shell.echo(`\n\nYou can now push if there are no conflicts`)
  }
}

function getBranches () {
  return exec(`git for-each-ref refs/heads refs/remotes --format='%(refname)'`)
    .split('\n')
    .map(ref => (
      /refs\/.*?\/(.*)/.exec(ref)[1]
    ))
}

@@ -726,27 +726,8 @@
 on)%0A
-    afterRelease()%0A
   %7D)
@@ -3365,180 +3365,86 @@
 )%0A  
-if (exec(%60git config branch.$%7Bbranch%7D.remote%60)) %7B%0A    shell.exec(%60git push --no-verify --follow-tags%60)%0A  %7D else %7B%0A    const remote = exec(%60git config branch.master.remote%60)
+shell.exec(%60git push --no-verify --follow-tags%60)%0A%0A  if (branch === 'master') %7B
 %0A   
@@ -3459,163 +3459,83 @@
 xec(
-%60
+'
 git 
-push --no-verify --follow-tags -u $%7Bremote%7D%60)%0A  %7D%0A%7D%0A%0Afunction afterRelease () %7B%0A  if (branch.match(/release%5C/.*/)) %7B%0A    const previousBranch = branch
+checkout dev')%0A    branch = 'dev'%0A    shell.exec('git pull --ff-only')
 %0A   
@@ -3551,24 +3551,21 @@
 ec('git 
-checkout
+merge
  master'
@@ -3570,30 +3570,60 @@
 r')%0A
+%0A
     
-branch = 'master'%0A
+if (exec('git status --porcelain') === '') %7B%0A  
     
@@ -3644,73 +3644,44 @@
 t pu
-ll --ff-only')%0A    shell.exec(%60git merge $%7BpreviousBranch%7D%60)%0A
+sh --no-verify')%0A    %7D else %7B%0A 
     
+ 
 shel
@@ -3691,45 +3691,23 @@
 cho(
-%60%5Cn%5CnYou can now push if ther
+'Pleas
 e 
-a
 re
- no
+solve
  con
@@ -3716,201 +3716,48 @@
 icts
-%60)%0A  %7D%0A%7D%0A%0Afunction getBranches () %7B%0A  return exec(%60git for-each-ref refs/heads refs/remotes --format='%25(refname)'%60)%0A    .split('%5Cn')%0A    .map(ref =%3E (%0A      /refs%5C/.*?%5C/(.*)/.exec(ref)%5B1%5D%0A    ))
+ then push the current branch')%0A    %7D%0A  %7D
 %0A%7D%0A

tidy up release script