#!/usr/bin/env ruby

require 'rubygems'
require 'clamp'
require 'highline'
HighLine.color_scheme = HighLine::SampleColorScheme.new

# load i18n to get translations
require 'hammer_cli/i18n'

require 'hammer_cli/options/normalizers'
# Create fake command instance to use some global args before we start.
# Option descriptions are never displayed and thus do not require translation.
class PreParser < Clamp::Command
  option ["-v", "--verbose"], :flag, "be verbose"
  option ["-d", "--debug"], :flag, "show debugging output"
  option ["-c", "--config"], "CFG_FILE", "path to custom config file" do |path|
    File.expand_path path
  end
  option ["-u", "--username"], "USERNAME", "username to access the remote system"
  option ["-p", "--password"], "PASSWORD", "password to access the remote system"
  option ["-s", "--server"], "SERVER", "remote system address"
  option ["-r", "--reload-cache"], :flag, "force reload of Apipie cache"
  option ["--interactive"], "INTERACTIVE", "Explicitly turn interactive mode on/off" do |value|
    bool_normalizer = HammerCLI::Options::Normalizers::Bool.new
    bool_normalizer.format(value)
  end
  option ["--version"], :flag, "show version"
  option ["--show-ids"], :flag, "Show ids of associated resources"
  option ["--csv"], :flag, "Output as CSV (same as --output=csv)"
  option ["--output"], "ADAPTER", "Set output format"
  option ["--csv-separator"], "SEPARATOR", "Character to separate the values"
  option ["--autocomplete"], "LINE", "Get list of possible endings"
end

preparser = PreParser.new File.basename($0), {}
begin
  preparser.parse ARGV
rescue
end

# load user's settings
require 'hammer_cli/settings'

CFG_PATH_LEGACY = ['~/.foreman/', '/etc/foreman/', "#{::RbConfig::CONFIG['sysconfdir']}/foreman/"].uniq
HammerCLI::Settings.load_from_paths CFG_PATH_LEGACY
if HammerCLI::Settings.path_history.empty?
  CFG_PATH = ['~/.hammer/', '/etc/hammer/', "#{::RbConfig::CONFIG['sysconfdir']}/hammer/"].uniq
  HammerCLI::Settings.load_from_paths CFG_PATH
else
  warn _("Warning: Legacy config paths detected, move the following files")
  HammerCLI::Settings.path_history.each { |p| warn "    #{p} -> #{p.gsub('hammer.modules.d', 'cli.modules.d').gsub('foreman/', 'hammer/')}"}
end

CFG_PATH_LOCAL = ['./config/']

HammerCLI::Settings.load_from_paths CFG_PATH_LOCAL

if preparser.config
  if File.file? preparser.config
    HammerCLI::Settings.load_from_file preparser.config
  elsif File.directory? preparser.config
    HammerCLI::Settings.load_from_paths [preparser.config]
  else
    $stderr.puts _('Error: Custom configuration file %s does not exist.') % preparser.config
    require 'hammer_cli/exit_codes'
    exit HammerCLI::EX_CONFIG
  end
end

# store username and password in settings
HammerCLI::Settings.load({
  :_params => {
    :username => preparser.username,
    :password => preparser.password,
    :host => preparser.server,
    :interactive => preparser.interactive,
    :verbose => preparser.verbose? || preparser.debug?,
    :reload_cache => preparser.reload_cache?
  }})

if HammerCLI::Settings.get(:mark_translated)
  include HammerCLI::I18n::Debug
end

# setup logging
require 'hammer_cli/logger'
logger = Logging.logger['Init']

if preparser.verbose? || preparser.debug?
  root_logger = Logging.logger.root
  root_logger.appenders = root_logger.appenders << ::Logging.appenders.stderr(:layout => HammerCLI::Logger::COLOR_LAYOUT)
  root_logger.level = 'debug' if preparser.debug?
end

require 'hammer_cli/version'
hammer_version = HammerCLI.version.to_s
logger.info "Initialization of Hammer CLI (#{hammer_version}) has started..."
logger.debug "Running at ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"


# log which config was loaded (now when we have logging)
HammerCLI::Settings.path_history.each do |path|
  logger.info "Configuration from the file #{path} has been loaded"
end

# load hammer core
require 'hammer_cli'

# load modules set in config
begin
  HammerCLI::Modules.load_all
rescue => e
  handler = HammerCLI::ExceptionHandler.new(:context => {}, :adapter => :base)
  handler.handle_exception(e)
  exit HammerCLI::EX_SOFTWARE
end

# log information about locale
logger.debug "Using locale '#{HammerCLI::I18n.locale}'"
HammerCLI::I18n.domains.each do |domain|
  logger.debug "'#{domain.type}' files for locale domain '#{domain.domain_name}' loaded from '#{File.expand_path(domain.locale_dir)}'"
end

exit HammerCLI::MainCommand.run || HammerCLI::EX_OK
