#!/usr/bin/env ruby

#    Copyright 2013 Mirantis, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

require 'astute'
require 'logger'
require 'ostruct'
require 'optparse'
require 'yaml'
require 'raemon'

options = OpenStruct.new
options.daemonize = false
options.pidfile = '/var/run/astuted.pid'
options.config_path = '/etc/astute/astuted.conf'
options.log_path = nil
options.log_level = 'debug'
options.workers = 1

OptionParser.new do |opts|
  opts.banner = 'Usage: astuted [options]'
  opts.separator "\nOptions:"
  opts.on('-d', '--[no-]daemonize', 'Daemonize server') do |flag|
    options.daemonize = flag
  end
  opts.on('-P', '--pidfile PATH', 'Path to pidfile') do |path|
    options.pidfile = path
  end
  opts.on('-w', '--workers NUMBER', 'Number of worker processes') do |number|
    options.workers = number.to_i
  end
  opts.on('-c', '--config PATH', 'Use custom config file') do |path|
    unless File.exists?(path)
      puts "Error: config file #{path} was not found"
      exit
    end
    options.config_path = path
  end
  opts.on('-l', '--logfile PATH' 'Log file path') do |path|
    options.log_path = path
  end
  levels = %w{fatal error warn info debug}
  opts.on('--loglevel LEVEL', levels, "Logging level (#{levels.join(', ')})") do |level|
    options.log_level = level
  end
  opts.on_tail('-h', '--help', 'Show this message') do
    puts opts
    exit
  end
  opts.on_tail('-v', '--version', 'Show version') do
    puts Astute::VERSION
    exit
  end
end.parse!

if options.daemonize
  # After daemonize we can't log to STDOUT, pick a default log file
  options.log_path ||= "#{Dir.pwd}/astute.log"
end

Astute.config.update(YAML.load(File.read(options.config_path))) if File.exists?(options.config_path)
Astute.logger = options.log_path ? Logger.new(options.log_path) : Logger.new(STDOUT)
Astute.logger.level = Logger.const_get(options.log_level.upcase)
Astute.logger.formatter = proc do |severity, datetime, progname, msg|
  severity_map = {'DEBUG' => 'DEBUG', 'INFO' => 'INFO', 'WARN' => 'WARNING', 'ERROR' => 'ERROR', 'FATAL' => 'CRITICAL'}
  "#{datetime.strftime("%Y-%m-%d %H:%M:%S")} #{severity_map[severity]} [#{Process.pid}] #{msg}\n"
end

Astute.logger.info "Starting with settings\n#{Astute.config.to_yaml}"

Raemon::Master.start(options.workers, Astute::Server::Worker,
  :detach   => options.daemonize,
  :name     => 'astute',
  :pid_file => options.pidfile,
  :logger   => Astute.logger
)
