#!/usr/bin/env ruby
# Make drb server
require 'rubygems'
require 'drb'
#require 'pry'
#require File.expand_path('../lib/in_memory_q_counter', File.dirname(__FILE__))
# This is a non thread safe replacement for the
# couchbase counter mechanism since every test needs
# a clean start and Hash#clear is soooo much faster than
# a couchbase bucket flush
class InMemoryQCounter
  attr_reader :store, :environment

  def initialize(reload_stats: false, environment: nil)
    @store = {}
    @environment = environment || 'development'
    reload_stats! if reload_stats
  end

  def get(key, options = {})
    value = store[key]
    debug "Get key #{key} (#{value})"
    value
  end

  def set(key, value)
    debug "Set key #{key} to #{value}"
    store[key] = value
  end

  def incr(key, options = {})
    debug "Increment key #{key}"
    # store[key] ||= options[:initial].to_i
    # store[key] += 1
    if store[key]
      store[key] += 1
    else
      store[key] = options[:initial].to_i
    end
  end

  def decr(key, options = {})
    debug "Decrement key #{key}"
    # store[key] ||= options[:initial].to_i
    # store[key] -= 1
    if store[key]
      store[key] -= 1
    else
      store[key] = options[:initial].to_i
    end
  end

  def flush
    debug "Flushing store"
    store.clear
  end

  def debug(message)
    puts message
  end

  def reload_stats!
    require 'yaml'
    require 'couchrest'
    require 'pry'
    couch_settings_path = 'config/couchdb.yml'
    puts "Couch settings path: #{couch_settings_path}"
    puts "Environment: #{environment.inspect}"
    couch_settings = YAML.load_file(couch_settings_path)[environment]
    database = couch_settings['database']
    db = CouchRest.database(database)
    design_doc = "_design/order_counter"
    view_path = File.join design_doc, "_view/by_supplier_id_and_state"
    tries = 0
    begin
      view_result = db.view(view_path, reduce: true, group: true, group_level: 2)
    rescue RestClient::ResourceNotFound => e
      puts "Database view #{view_path} not found"
      design_doc_path = File.expand_path('../couchdb_design.yml', __FILE__)
      doc = YAML.load_file design_doc_path
      doc['_id'] = design_doc
      db.save_doc(doc)
      if tries < 3
        tries += 1
        retry
      else
        raise e
      end
      # view not available, initialize as zero
    end
    counts = view_result ? view_result['rows'] : nil
    puts "Initialize with: #{counts.to_yaml}"
    if counts
      counts.each do |count_spec|
        supplier_id, order_state = count_spec['key']
        order_count = count_spec['value']
        case order_state
        when "placed" then set("supplier_counter:#{supplier_id}:orders_placed", order_count)
        when "active" then set("supplier_counter:#{supplier_id}:orders_in_process", order_count)
        end
      end
    end
  rescue => e
    raise e
  end
end
drb_port = 9022
environment = (%w[production staging development test] & ARGV).first || 'development'
DRb.start_service "druby://:#{drb_port}", InMemoryQCounter.new(reload_stats: false, environment: environment)
DRb.thread.join
