require 'json'
require 'resque'
require 'resque-retry'
require 'net/http'
require 'digest/md5'

module JamRuby
  class JamTracksBuilder
    extend JamRuby::ResqueStats
    attr_accessor :jam_track_right_id, :bitrate
    @queue = :jam_tracks_builder

    def log
      @log || Logging.logger[JamTracksBuilder]
    end

    def self.perform(jam_track_right_id, bitrate=48)      
      jam_track_builder = JamTracksBuilder.new()
      jam_track_builder.jam_track_right_id = jam_track_right_id
      jam_track_builder.bitrate=bitrate
      jam_track_builder.run
    end

    def run
      self.bitrate ||= 48
      begin
        log.info("jam_track_builder job starting. jam_track_right_id #{jam_track_right_id}, bitrate: #{self.bitrate}")
        begin
          @jam_track_right = JamTrackRight.find(jam_track_right_id)

          # bailout check
          if @jam_track_right.signed?(bitrate)
            log.debug("package is already signed. bailing")
            return
          end

          # compute the step count
          total_steps = @jam_track_right.jam_track.stem_tracks.count + 1 # the '1' represents the jkz.py invocation

          # track that it's started ( and avoid db validations )
          signing_started_at = Time.now
          signing_started_model_symbol = bitrate == 48 ? :signing_started_at_48 : :signing_started_at_44
          signing_state_symbol = bitrate == 48 ? :signing_48 : :signing_44
          last_step_at = Time.now
          JamTrackRight.where(:id => @jam_track_right.id).update_all(signing_started_model_symbol => signing_started_at, :should_retry => false, packaging_steps: total_steps, current_packaging_step: 0, last_step_at: last_step_at, signing_state_symbol => true, queued: false)
          # because we are skipping 'after_save', we have to keep the model current for the notification.  A bit ugly...
          @jam_track_right.current_packaging_step = 0
          @jam_track_right.packaging_steps = total_steps
          @jam_track_right[signing_started_model_symbol] = signing_started_at
          @jam_track_right[signing_state_symbol] = true
          @jam_track_right.should_retry = false
          @jam_track_right.last_step_at = Time.now
          @jam_track_right.queued = false
          SubscriptionMessage.jam_track_signing_job_change(@jam_track_right)
          JamRuby::JamTracksManager.save_jam_track_right_jkz(@jam_track_right, self.bitrate)

          # If bitrate is 48 (the default), use that URL.  Otherwise, use 44kHz:
          length = (self.bitrate==48) ? @jam_track_right.url_48.size() : @jam_track_right.url_44.size()
          md5 = Digest::MD5.new
          @jam_track_right.finish_sign(length, md5.to_s, self.bitrate)

          log.info "Signed #{self.bitrate}kHz jamtrack to #{@jam_track_right[:url]}"
        rescue Exception => e
          # record the error in the database
          post_error(e)
          # and let the job fail, alerting ops too
          raise
        end
      end
    end

    # set @error_reason before you raise an exception, and it will be sent back as the error reason
    # otherwise, the error_reason will be unhandled-job-exception
    def post_error(e)
      begin
        # if error_reason is null, assume this is an unhandled error
        unless @error_reason
          @error_reason = "unhandled-job-exception"
          @error_detail = e.to_s
        end
        @jam_track_right.finish_errored(@error_reason, @error_detail, self.bitrate)

      rescue Exception => e
        log.error "unable to post back to the database the error #{e}"
      end
    end
  end
end
