text: require 'date'
  require 'moped'
  
  require 'prolly/ps/storage/base'
  
  module Prolly
    class Ps
      module Storage
  
        class Mongodb < Base
  
          attr_reader :session
  
          def initialize
            @session ||= Moped::Session.new(["127.0.0.1:27017", "127.0.0.1:27018"])
            @session.use 'pspace'
  
            super
            @rand_vars = []
          end
  
          def reset
            super
            @session['samples'].drop
          end
  
          def add(datum)
            # create an index for each new datum key
            #new_rvs(datum).each do |rv|
            #  @session.indexes.create(rv.to_sym => 1)
            #end
  
            record_new_rand_vars(datum)
  
            @session[:samples].insert(datum)
          end
  
          def count(rvs, options = {})
            reload = options["reload"] || false
            if rvs.kind_of?(Array)
              @session[:samples].find(
                Hash[*rvs.flat_map { |rv| [rv, { '$exists' => true }] }]
              ).count
            elsif rvs.kind_of?(Hash)
              @session[:samples].find(to_query_hash(rvs)).count
            end
          end
  
          def rand_vars
            @session[:rand_vars].find.map { |rv| rv[:name] }
          end
  
          def uniq_vals(name)
            @session[:samples].aggregate([
              { "$match" => { name.to_sym => { "$exists" => true } } },
              { "$group" => { "_id": "$#{name}" } }
            ]).map { |e| e["_id"] }
          end
  
          private
  
          def new_rvs(datum)
            return datum.keys - rand_vars 
          end
  
          def record_new_rand_vars(datum)
            new_rvs(datum).each do |rv|
              @session[:rand_vars].insert({ name: rv })
            end
          end
  
          def to_query_hash(rvs)
            Hash[*rvs.flat_map { |k, v|
              [k, v.kind_of?(Array) ? { "$in" => v } : v]
            }]
          end
  
        end
  
      end
    end
  end
  