class Github::PageIterator

def first

def first
  return nil unless first_page_uri
  response = if next_page < 1
    parsed_query = parse_query(first_page_uri.split(QUERY_STR_SEP).last)
    params = {}
    if parsed_query.keys.include?('sha')
      params['sha'] = 'master'
    end
    params['per_page'] = parse_per_page_number(first_page_uri)
    page_request first_page_uri.split(QUERY_STR_SEP).first, params
  else
    page_request first_page_uri.split(QUERY_STR_SEP).first,
                       'per_page' => parse_per_page_number(first_page_uri)
  end
  update_page_links response.links
  response
end

def get_page(page_number)

Returns the result for a specific page.
def get_page(page_number)
  # Find URI that we can work with, if we cannot get the first or the
  # last page URI then there is only one page.
  page_uri = first_page_uri || last_page_uri
  return nil unless page_uri
  params   = parse_query page_uri.split(QUERY_STR_SEP).last
  params['page'] = page_number
  params['per_page'] = parse_per_page_number(page_uri)
  response = page_request page_uri.split(QUERY_STR_SEP).first, params
  update_page_links response.links
  response
end

def has_next?

def has_next?
  next_page == 0 || !next_page_uri.nil?
end

def initialize(env)

def initialize(env)
  @links = Github::PageLinks.new(env[:response_headers])
  update_page_links @links
end

def last

def last
  return nil unless last_page_uri
  params   = parse_query last_page_uri.split(QUERY_STR_SEP).last
  params['page'] = parse_page_number(last_page_uri)
  params['per_page'] = parse_per_page_number(last_page_uri)
  response = page_request last_page_uri.split(QUERY_STR_SEP).first, params
  update_page_links response.links
  response
end

def next

def next
  return nil unless has_next?
  response = if next_page < 1
    parsed_query = parse_query(next_page_uri.split(QUERY_STR_SEP).last)
    params = {}
    if parsed_query.keys.include?('last_sha')
      params['sha'] = parsed_query['last_sha']
    end
    params['per_page'] = parse_per_page_number(next_page_uri)
    page_request next_page_uri.split(QUERY_STR_SEP).first, params
  else
    params = parse_query next_page_uri.split(QUERY_STR_SEP).last
    params['page'] = parse_page_number(next_page_uri)
    params['per_page'] = parse_per_page_number(next_page_uri)
    page_request next_page_uri.split(QUERY_STR_SEP).first, params
  end
  update_page_links response.links
  response
end

def parse_page_number(uri) # :nodoc:

:nodoc:
def parse_page_number(uri) # :nodoc:
  parse_page_params(uri, PARAM_PAGE)
end

def parse_page_params(uri, attr) # :nodoc:

:nodoc:
Extracts query string parameter for given name
def parse_page_params(uri, attr) # :nodoc:
  return -1 if uri.nil? || uri.empty?
  parsed = nil
  begin
    parsed = URI.parse(uri)
  rescue URI::Error => e
    return -1
  end
  param = parse_query_for_param(parsed.query, attr)
  return -1 if param.nil? || param.empty?
  begin
    return param.to_i
  rescue ArgumentError => err
    return -1
  end
end

def parse_per_page_number(uri) # :nodoc:

:nodoc:
def parse_per_page_number(uri) # :nodoc:
  parse_page_params(uri, PARAM_PER_PAGE)
end

def prev

def prev
  return nil unless prev_page_uri
  params   = parse_query prev_page_uri.split(QUERY_STR_SEP).last
  params['page'] = parse_page_number(prev_page_uri)
  params['per_page'] = parse_per_page_number(prev_page_uri)
  response = page_request prev_page_uri.split(QUERY_STR_SEP).first, params
  update_page_links response.links
  response
end

def update_page_links(links) # :nodoc:

:nodoc:
Wholesale update of all link attributes
def update_page_links(links) # :nodoc:
  ATTRIBUTES.each do |attr|
    self.send(:"#{attr}_page_uri=", links.send(:"#{attr}"))
    self.send(:"#{attr}_page=", parse_page_number(links.send(:"#{attr}")))
  end
end