#!/usr/bin/env ruby

require 'active_support'
require 'active_support/core_ext'
require 'thor'

module ActionSubscriber
  class CLI < ::Thor
    class_option :app, :default => "./config/environment.rb"
    class_option :mode
    class_option :host
    class_option :hosts
    class_option :pop_interval, :type => :numeric, :desc => "how long to wait between asking for messages (in milliseconds)"
    class_option :port, :type => :numeric
    class_option :threadpool_size, :type => :numeric
    class_option :times_to_pop, :type => :numeric, :desc => "how many messages to get from each queue each time we ask rabbit"

    desc "start", "Start the action subscriber subscription server"
    long_desc <<-BABOUDESC.strip_heredoc
      Action Subscriber contains a simple subscriber server to manage event subscriptions in a separate process.
    BABOUDESC

    def start
      require options[:app]

      $0 = "Action Subscriber server #{object_id}"
      puts "Loading configuration..."

      ::ActionSubscriber::Configuration.configure_from_yaml_and_cli(options)
      puts "Starting server..."

      case ::ActionSubscriber.configuration.mode
      when /pop/i then
        ::ActionSubscriber::Babou.auto_pop!
      when /subscribe/i then
        ::ActionSubscriber::Babou.start_subscribers
      end
    end
  end

  [:INT, :QUIT, :TERM].each do |signal|
    trap(signal) do
      puts "Stopping server..."
      wait_loops = 0
      ::ActionSubscriber::Babou.stop_server!

      # Going to wait until the thread pool drains or we wait for 1000 seconds
      # Only waiting for shut down in pop mode
      if ::ActionSubscriber::Babou.pop?
        while ::ActionSubscriber::Threadpool.pool.busy_size > 0 && wait_loops < 1000
          Thread.pass
          wait_loops = wait_loops + 1
          sleep 1
        end
      end

      exit 0
    end
  end
end

trap(:TTIN) {
  ::ActionSubscriber.print_subscriptions
}

trap(:USR2) {
  puts <<-CONFIG.strip_heredoc
  Action Subscriber Stats
    Pool Size: #{ ::ActionSubscriber.config.threadpool_size }
    Ready Size: #{ ::ActionSubscriber::Threadpool.ready_size }
  CONFIG
}

::ActionSubscriber::CLI.start(ARGV)
