require 'json'
require 'open-uri'

def base_url
  "http://w...content-available-to-author-only...t.com/r/dailyprogrammer.json?limit=100000&after="
end

def pull(before='')
  target_url = base_url + before.to_s
  puts "PULLING #{target_url}"
  results = open(target_url).readlines.join

  posts   = JSON.parse(results, symbolize_names: true)

  # Discard occasional empty hash
  posts   = posts.select { |p| p.is_a?(Hash) && !p.empty? }.first 
  posts   = posts.fetch(:data).fetch(:children)

  posts   = posts.map    { |p| p[:data] }
  posts   = posts.select { |p| p[:title].include?('#') }
  posts   = posts.map    { |p| Challenge.new(p) }.sort
end

def dataset
  @dataset ||= get_all
end

def get_all
  all_posts = []
  next_id = ''

  while all_posts.empty? || (all_posts.map(&:challenge_id).min > 1)
    new_posts = pull(next_id)
    all_posts.concat(new_posts)
    all_posts.sort!.uniq!
    next_id   = all_posts.first.reddit_id
  end

  return all_posts.uniq.sort
end

def main
  return dataset
end


class Challenge
  attr_accessor :raw

  def initialize(hash={})
    @raw       = hash
    self
  end

  def difficulty
    return @difficulty unless @difficulty.nil?
    return @difficulty = 0 if self.title.downcase.include?('easy')
    return @difficulty = 1 if self.title.downcase.include?('intermediate')
    return @difficulty = 2
  end

  def title
    @title ||= @raw[:title]
  end

  def challenge_id
    begin
      @challenge_id ||= title.split('#')[1].split(' ').first.to_i
    rescue
      -1
    end
  end

  def hash
    [self.challenge_id].hash
  end

  def eql?(other)
    self.hash == other.hash
  end

  def reddit_id
    @reddit_id ||= @raw[:name].to_s
  end

  def url
    @url ||= @raw[:url]
  end

  def to_s
    "[#{%w(Easy Intermediate Difficult)[self.difficulty]}] #{self.title} #{self.url}"
  end

  def <=>(other)
    return -1 if self.challenge_id < other.challenge_id
    return  0 if self.challenge_id == other.challenge_id
    return  1
  end
end

main