Container = require '../Container.coffee'
util = require '../util'
# Errors
BAD_PARAM_ERR = new Error('Invalid job params passed')
BUILD_NOT_FOUND = new Error('Build not found')
INVALID_ACTION = new Error('Action not supported')

module.exports = class Worker
  constructor: (@model, @kue) ->
    console.log 'new worker created'
    @start()
  start: ->
    @kue.process 'buildTask', (job, done) =>
      @process job, (err) =>
        @cleanWorkerState()
        done err

    stopOnRemove = (id) =>
      return unless id.toString() == @jobId?.toString()
      console.log '** Active job was removed. Killing process **'
      if @container
        util.sendToSlackImmediate ":docker: Stopped Build -- #{@buildId} :docker:", ->
          process.exit()
      else
        process.exit()
    @kue.on 'job remove', stopOnRemove

  process: (job, done) ->
    return done(BAD_PARAM_ERR) unless @action = job.data?.action
    return done(BAD_PARAM_ERR) unless @buildId = job.data?.buildId
    util.sendToSlack ":docker: Starting #{@action} -- #{@buildId} :docker:"
    console.log 'Kue Job:', job.id, job.data
    @jobId = job.id
    @options = job.data.options || {}
    @$build = @model.DockerBuild.at @buildId
    @$build.subscribe (err) =>
      return done err if err
      return done(INVALID_ACTION) unless @["_#{@action}"]
      return done(BUILD_NOT_FOUND) unless @$build.get()
      @container = new Container @model, @buildId
      @["_#{@action}"] (err) =>
        if err
          @$build.set 'succeeded', false
          @container.captureLog ":docker: #{@action} failed -- #{@buildId} :docker:", {echo: true, slack: true}
          return done err
        @$build.set 'succeeded', true
        @container.captureLog ":docker: Finished #{@action} -- #{@buildId} :docker:", {echo: true, slack: true}
        done()

  cleanWorkerState: ->
    @jobId = null
    @action = null
    @buildId = null
    @$build = null
    @container = null

  _build: (done) ->
    @container.pullRepo()
    @container.build (err) =>
      return done err if err
      @container.saveNpmLs()
      if @options.buildOnly
        return done()
      @container.push (err) ->
        return done err if err
        done()

  _push: (done) ->
    @container.push (err) ->
      done err if err

  _deploy: (done) ->
    @container.deploy done
