class LHC::Caching

def after_response(response)

def after_response(response)
  return unless response.success?
  request = response.request
  return unless cache?(request)
  options = options(request.options)
  cache_for(options).write(
    key(request, options[:key]),
    to_cache(response),
    cache_options(options)
  )
end

def before_request(request)

def before_request(request)
  return unless cache?(request)
  deprecation_warning(request.options)
  options = options(request.options)
  key = key(request, options[:key])
  response_data = cache_for(options).fetch(key)
  return unless response_data
  logger.info "Served from cache: #{key}" if logger
  from_cache(request, response_data)
end

def cache?(request)

return false if this interceptor cannot work
based on the options, this method will
do we even need to bother with this interceptor?
def cache?(request)
  return false unless request.options[:cache]
  options = options(request.options)
  cache_for(options) &&
    cached_method?(request.method, options[:methods])
end

def cache_for(options)

return the cache for the given options
def cache_for(options)
  options.fetch(:use, cache)
end

def cache_options(input = {})

the cache
extracts the options that should be forwarded to
def cache_options(input = {})
  input.each_with_object({}) do |(key, value), result|
    result[key] = value if key.in? FORWARDED_OPTIONS
    result
  end
end

def cached_method?(method, cached_methods)

in regards of the provided options.
Checks if the provided method should be cached
def cached_method?(method, cached_methods)
  (cached_methods || [:get]).include?(method)
end

def deprecated_keys(request_options)

grabs the deprecated keys from the request options
def deprecated_keys(request_options)
  request_options.keys.select { |k| k =~ /^cache_.*/ }.sort
end

def deprecation_warning(request_options)

emits a deprecation warning if necessary
def deprecation_warning(request_options)
  unless deprecated_keys(request_options).empty?
    ActiveSupport::Deprecation.warn(
      "Cache options have changed! #{deprecated_keys(request_options).join(', ')} are deprecated and will be removed in future versions."
    )
  end
end

def from_cache(request, data)

converts json we read from the cache to an LHC::Response object
def from_cache(request, data)
  raw = Typhoeus::Response.new(data)
  response = LHC::Response.new(raw, request, from_cache: true)
  request.response = response
  response
end

def key(request, key)

def key(request, key)
  unless key
    key = "#{request.method.upcase} #{request.url}"
    key += "?#{request.params.to_query}" unless request.params.blank?
  end
  "LHC_CACHE(v#{CACHE_VERSION}): #{key}"
end

def map_deprecated_options!(request_options, options)

maps `cache_key` -> `key`, `cache_expires_in` -> `expires_in` and so on
def map_deprecated_options!(request_options, options)
  deprecated_keys(request_options).each do |deprecated_key|
    new_key = deprecated_key.to_s.gsub(/^cache_/, '').to_sym
    options[new_key] = request_options[deprecated_key]
  end
end

def options(request_options)

will map deprecated options to the new format
returns the request_options
def options(request_options)
  options = request_options[:cache] == true ? {} : request_options[:cache].dup
  map_deprecated_options!(request_options, options)
  options
end

def to_cache(response)

converts a LHC::Response object to json, we store in the cache
def to_cache(response)
  data = {}
  data[:body] = response.body
  data[:code] = response.code
  # convert into a actual hash because the typhoeus headers object breaks marshaling
  data[:headers] = response.headers ? Hash[response.headers] : response.headers
  # return_code is quite important as Typhoeus relies on it in order to determin 'success?'
  data[:return_code] = response.options[:return_code]
  # in a test scenario typhoeus uses mocks and not return_code to determine 'success?'
  data[:mock] = response.mock
  data
end