/**
 * @module lib/watcher
 * @exports {Class} Watcher
 */
'use strict'

const fs = require('fs')
const nodeWatch = require('node-watch')
const path = require('path')

const Git = require('./git')
const Output = require('./output')

// const api = require('./api')

class Watcher extends Output {
  /**
   * @constructor
   * @param {InstanceModel} instance
   */
  constructor (instance) {
    super()
    this._instance = instance
  }

  // EDIT: PATCH https://api.runnable.io/instances/55d3aa87b222f91c0036b2c3/containers/85af5a0438b1b82dc4a3b6515546f770cf2fc62270bcc350b3eb5a6d1c624963/files/api/README.md
  //   - body: <string>
  //
  // CREATE: PATCH https://api.runnable.io/instances/55d3aa87b222f91c0036b2c3/containers/85af5a0438b1b82dc4a3b6515546f770cf2fc62270bcc350b3eb5a6d1c624963/files/newFile
  //   - isDir: <boolean>
  //   - name: <string>
  //
  // RENAME: PATCH https://api.runnable.io/instances/55d3aa87b222f91c0036b2c3/containers/85af5a0438b1b82dc4a3b6515546f770cf2fc62270bcc350b3eb5a6d1c624963/files/tempfile
  //   NOTE: tempfile --> screwit
  //   - isDir: <boolean>
  //   - name: <string>

  /**
   * Watch pwd for file changes
   * When a file change is detected, run `git check-ignore` to see if the file is ignored by the
   * repository. Process the file if it is not ignored.
   */
  watch () {
    var git = new Git()
    var cwd = process.cwd()
    nodeWatch(process.cwd(), (filePath) => {
      var rel = path.relative(cwd, filePath)
      git.checkIgnore(rel).then((excluded) => {
        if (!excluded) { this._handleFileChange(rel) }
      })
    })
  }

  /**
   * @param {String} filePath - relative filepath
   */
  _handleFileChange (filePath) {
    // var contents = '';
    var spinStringBase = [
      './',
      filePath,
      ' --> [remote]:',
      '/',
      this._instance.repositoryName(),
      '/',
      filePath
    ].join('')

    var stats = this._fetchContents(filePath)
    if (stats.deleted) {
      // spinString += ' DELETE'
      // spinner = new Spinner(spinString.magenta)
      // spinner.start()
      // spinner.stop()
    } else {
      var stopSpinner = this.spinner(spinStringBase + ' %s', spinStringBase + ' [complete]')
      this._instance.uploadFile(filePath, stats.contents)
        .then((instance) => {
          stopSpinner()
          this._instance = instance
        })
    }
  }

  /**
   * @return Object
   *   - deleted
   *   - isDir
   *   - contents
   */
  _fetchContents (filepath) {
    var contents
    try {
      contents = fs.readFileSync(filepath)
    } catch (e) {
      if (e.code === 'ENOENT') {
        // file deleted
        return {
          deleted: true
        }
      }
      if (e.code === 'EISDIR') {
        // it's a dir not a file
        return {
          deleted: false,
          isDir: true,
          contents: ''
        }
      }
    }
    return {
      deleted: false,
      isDir: false,
      contents: contents.toString()
    }
  }
}

module.exports = Watcher

@@ -66,16 +66,52 @@
 trict'%0A%0A
+const Promise = require('bluebird')%0A
 const fs
@@ -1507,43 +1507,63 @@
     
-git.checkIgnore(rel).then((
+Promise.coroutine(function *() %7B%0A        const 
 excluded
 ) =%3E
@@ -1558,22 +1558,45 @@
 excluded
-)
  =
-%3E %7B
+ yield git.checkIgnore(rel)
 %0A       
@@ -1612,16 +1612,26 @@
 luded) %7B
+%0A         
  this._h
@@ -1650,16 +1650,24 @@
 nge(rel)
+%0A       
  %7D%0A     
@@ -1664,24 +1664,37 @@
    %7D%0A      %7D
+.bind(this))(
 )%0A    %7D)%0A  %7D
@@ -1820,19 +1820,21 @@
 '';%0A    
-var
+const
  spinStr
@@ -1993,19 +1993,21 @@
 ')%0A%0A    
-var
+const
  stats =
@@ -2214,19 +2214,21 @@
 %7B%0A      
-var
+const
  stopSpi
@@ -2313,159 +2313,166 @@
     
-this._instance.uploadFile(filePath, stats.contents)%0A        .then((instance) =%3E %7B%0A          stopSpinner()%0A          this._instance = instance%0A        %7D
+Promise.coroutine(function *() %7B%0A        this._instance = yield this._instance.uploadFile(filePath, stats.contents)%0A        stopSpinner()%0A      %7D.bind(this))(
 )%0A  

Use generators for Watcher class instance methods