'use strict'

let cli = require('heroku-cli-util')
let fs = require('fs')
let uuid = require('node-uuid')
let os = require('os')
let path = require('path')
let exec = require('child_process').execSync
let nodeTar = require('../../lib/node_tar')

function compressSource (context, cwd, tempFile) {
  return new Promise(function (resolve, reject) {
    var tar = context.flags['tar'] || 'tar'
    let tarVersion = ''

    try {
      tarVersion = exec(tar + ' --version').toString()
    } catch (err) {
      // tar was not found on the system
    }

    if (tarVersion.match(/GNU tar/)) {
      let includeVcsIgnore = context.flags['include-vcs-ignore']
      let command = tar + ' cz -C ' + cwd + ' --exclude .git --exclude .gitmodules .'

      if (!includeVcsIgnore) {
        command += ' --exclude-vcs-ignores'
      }

      exec(command + ' > ' + tempFile)
      resolve()
    } else {
      cli.warn('Couldn\'t detect GNU tar. Builds could fail due to decompression errors')
      cli.warn('See https://devcenter.heroku.com/articles/platform-api-deploying-slugs#create-slug-archive')
      cli.warn('Please install it, or specify the \'--tar\' option')
      cli.warn('Falling back to node\'s built-in compressor')
      nodeTar.call(cwd, tempFile).then(resolve, reject)
    }
  })
}

function uploadCwdToSource (context, heroku, cwd) {
  return new Promise(function (resolve, reject) {
    let tempFilePath = path.join(os.tmpdir(), uuid.v4() + '.tar.gz')

    heroku.request({
      method: 'POST',
      path: '/sources'
    }).then(function (source) {
      compressSource(context, cwd, tempFilePath).then(function () {
        var stream = fs.createReadStream(tempFilePath)
        stream.on('close', function () {
          fs.unlink(tempFilePath)
        })

        cli.got.put(source.source_blob.put_url, {
          body: stream,
          headers: {
            'Content-Type': '',
            'Content-Length': fs.statSync(tempFilePath).size
          }
        }).then(function () {
          resolve(source.source_blob.get_url)
        }, reject)
      }, reject)
    }, reject)
  })
}

function create (context, heroku) {
  var sourceUrl = context.flags['source-url']
  var cwd = context.flags['cwd'] || process.cwd()

  var sourceUrlPromise = sourceUrl
    ? new Promise(function (resolve) { resolve(sourceUrl) })
    : new Promise(function (resolve, reject) { uploadCwdToSource(context, heroku, cwd).then(resolve, reject) })

  return new Promise(function (resolve, reject) {
    sourceUrlPromise.then(function (sourceGetUrl) {
      heroku.request({
        method: 'POST',
        path: `/apps/${context.app}/builds`,
        body: {
          source_blob: {
            url: sourceGetUrl,
            // TODO provide better default, eg. archive md5
            version: context.flags.version || ''
          }
        }
      }).then(function (build) {
        let stream = cli.got.stream(build.output_stream_url)
        stream.on('error', reject)
        stream.on('end', resolve)
        let piped = stream.pipe(process.stderr)
        piped.on('error', reject)
      }, reject)
    }, reject)
  })
}

module.exports = {
  topic: 'builds',
  command: 'create',
  needsAuth: true,
  needsApp: true,
  help: 'Create build from contents of current dir',
  description: 'create build',
  flags: [
    { name: 'source-url', description: 'source URL that points to the tarball of your application\'s source code', hasValue: true },
    { name: 'cwd', description: 'the local path to build. Defaults to pwd', hasValue: true },
    { name: 'tar', description: 'path to the executable GNU tar', hasValue: true },
    { name: 'version', description: 'description of your new build', hasValue: true },
    { name: 'include-vcs-ignore', description: 'include files ignores by VCS (.gitignore, ...) from the build' }
  ],
  run: cli.command(create)
}

@@ -1277,32 +1277,38 @@
 )%0A    %7D%0A  %7D)%0A%7D%0A%0A
+async 
 function uploadC
@@ -1347,60 +1347,8 @@
 ) %7B%0A
-  return new Promise(function (resolve, reject) %7B%0A  
   le
@@ -1414,324 +1414,111 @@
 z')%0A
-%0A    heroku.request(%7B%0A      method: 'POST',%0A      path: '/sources'%0A    %7D).then(function (source) %7B%0A      compressSource(context, cwd, tempFilePath).then(function () %7B%0A        var stream = fs.createReadStream(tempFilePath)%0A        stream.on('close', function () %7B%0A          fs.unlink(tempFilePath)%0A        %7D)%0A%0A       
+  let source = await heroku.post('/sources')%0A  await compressSource(context, cwd, tempFilePath)%0A  await
  cli
@@ -1564,34 +1564,49 @@
     
-      body: stream,%0A      
+body: fs.createReadStream(tempFilePath),%0A
     
@@ -1612,30 +1612,24 @@
  headers: %7B%0A
-      
       'Conte
@@ -1642,22 +1642,16 @@
 e': '',%0A
-      
       'C
@@ -1705,147 +1705,50 @@
     
-      %7D%0A        %7D).then(function () %7B%0A          resolve(source.source_blob.get_url)%0A        %7D, reject)%0A      %7D, reject)%0A    %7D, reject)%0A  %7D)
+%7D%0A  %7D)%0A  return source.source_blob.get_url
 %0A%7D%0A%0A

simplify uploadCwdToSource