class RemoteStorageAuthorization < ApplicationRecord
  belongs_to :user

  serialize :permissions

  validates_presence_of :permissions
  validates_presence_of :client_id

  scope :valid, -> { where(expire_at: nil).or(where(expire_at: (DateTime.now)..)) }
  scope :expired, -> { where(expire_at: ..(DateTime.now)) }

  after_initialize do |a|
    a.permissions = [] if a.permissions == nil
  end

  before_create  :generate_token
  before_create  :store_token_in_redis
  after_create   :schedule_token_expiry
  before_destroy :delete_token_from_redis
  after_destroy  :remove_token_expiry_job

  def url
    if self.redirect_uri
      uri = URI.parse self.redirect_uri
      "#{uri.scheme}://#{client_id}"
    else
      "http://#{client_id}"
    end
  end

  def delete_token_from_redis
    key = "rs:authorizations:#{user.address}:#{token}"
    redis.srem? key, redis.smembers(key)
  end

  private

    def redis
      @redis ||= Redis.new(url: Setting.rs_redis_url)
    end

    def generate_token(length=16)
      self.token = SecureRandom.hex(length) if self.token.blank?
    end

    def store_token_in_redis
      redis.sadd "rs:authorizations:#{user.address}:#{token}", permissions
    end

    def schedule_token_expiry
      return unless expire_at.present?
      RemoteStorageExpireAuthorizationJob.set(wait_until: expire_at)
                                         .perform_later(id)
    end

    def remove_token_expiry_job
      queue = Sidekiq::Queue.new(RemoteStorageExpireAuthorizationJob.queue_name)
      queue.each do |job|
        next unless job.display_class == "RemoteStorageExpireAuthorizationJob"
        job.delete if job.display_args == [id]
      end
    end
end
