#!/usr/lib/ruby/bin/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', '--[no-]verbose'], :flag, _('Be verbose (or not). True by default')
  option ['--[no-]use-defaults'], :flag, _('Enable/disable stored defaults. Enabled by default')
  option ['-q', '--quiet'], :flag, _('Completely silent')
  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 ["--no-headers"], :flag, "Hide headers from output"
  option ["--output-file"], "OUTPUT_FILE", "Path to custom output file"
  option ["--csv-separator"], "SEPARATOR", "Character to separate the values"
  option ["--autocomplete"], "LINE", "Get list of possible endings"
  option ["--verify-ssl"], "VERIFY_SSL", "Configure SSL verification of remote system" do |value|
    bool_normalizer = HammerCLI::Options::Normalizers::Bool.new
    bool_normalizer.format(value)
  end
  option ["--ssl-ca-file"], "CA_FILE", "Configure the file containing the CA certificates"
  option ["--ssl-ca-path"], "CA_PATH", "Configure the directory containing the CA certificates"
  option ["--ssl-client-cert"], "CERT_FILE", "Configure the client's public certificate"
  option ["--ssl-client-key"], "KEY_FILE", "Configure the client's private key"
  option ["--ssl-with-basic-auth"], :flag, "Use standard authentication in addition to client certificate authentication"
  option ["--fetch-ca-cert"], "SERVER", "Fetch CA certificate from server and exit"
end

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

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

HammerCLI::Settings.load_from_defaults

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,
    :debug => preparser.debug?,
    :no_headers => preparser.no_headers?,
    :reload_cache => preparser.reload_cache?,
    :verify_ssl => preparser.verify_ssl,
    :ssl_ca_file => preparser.ssl_ca_file,
    :ssl_ca_path => preparser.ssl_ca_path,
    :ssl_client_cert => preparser.ssl_client_cert,
    :ssl_client_key => preparser.ssl_client_key,
    :ssl_with_basic_auth => preparser.ssl_with_basic_auth?
  }})

HammerCLI::Settings.load({:use_defaults => preparser.use_defaults?}) unless preparser.use_defaults?.nil?

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

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

if 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'
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'

if preparser.fetch_ca_cert
  require 'hammer_cli/ca_cert_fetcher'
  ca_path = HammerCLI::SSLOptions.new.get_local_ca_store_path
  exit HammerCLI::CACertFetcher.new.fetch_ca_cert(preparser.fetch_ca_cert, ca_path)
end

# 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(File.basename($0), ARGV, HammerCLI.context) || HammerCLI::EX_OK