module ResqueJobs
  class Job
    include ActiveModel::Model

    PER_PAGE = 50
    Status = Resque::Plugins::Status

    attr_accessor :uuid, :name, :time, :status, :message, :num, :total, :error_message, :url, :options

    alias :id :uuid

    def initialize(options = {})
      %w{uuid time name status message num total error_message url options}.each do |key|
        send "#{key}=", options[key]
      end
    end

    def self.all(options = {})
      page = (options[:page].presence || 1).to_i
      limit = (page - 1) * PER_PAGE
      offset = limit + PER_PAGE - 1

      jobs = Status::Hash.statuses(limit, offset).map do |job_attributes|
        new job_attributes
      end

      PaginatedArray.new(jobs).tap do |a|
        a.total_count = Status::Hash.count
        a.per_page = PER_PAGE
      end
    end

    def self.find(id)
      job_attributes = Status::Hash.get id
      new(job_attributes) if job_attributes.present?
    end

    def self.delete_all
      Status::Hash.killall
      Status::Hash.clear
    end

    def self.delete_completed
      Status::Hash.clear_completed
    end

    def self.delete_failed
      Status::Hash.clear_failed
    end

    def pct_complete
      return "0%" if num.blank? || total.blank?
      (num * 100.0 / total).floor.to_s + "%"
    end

    def human_readable_name
      name.gsub(/["{}]/, "").truncate(50) if name.present?
    end

    def kill
      Status::Hash.kill id
    end

    def delete
      Status::Hash.remove id
    end

    def destroy
      kill && delete
    end

    def stopped?
      killed? || failed?
    end

    def active?
      queued? || working?
    end

    def to_param
      id
    end

    def job_started
      time ? Time.at(time) : nil
    end

    ['job_type', 'reporter', 'reporter_email'].each do |m|
      define_method(m) do
        options[m]
      end
    end

    [Status::STATUS_QUEUED, Status::STATUS_WORKING, Status::STATUS_COMPLETED, Status::STATUS_KILLED, Status::STATUS_FAILED].each do |m|
      define_method("#{m}?") do
        status == m
      end
    end
  end
end
