#!/usr/bin/env ruby

# Needed to make the client work on Ruby 1.8.7
unless Kernel.respond_to?(:require_relative)
  module Kernel
    def require_relative(path)
      require File.join(File.dirname(caller[0]), path.to_str)
    end
  end
end

require 'rubygems'
require 'gettext-setup'
require_relative "../lib/razor/cli"

GettextSetup.initialize(File.absolute_path('locales', File.dirname(File.dirname(__FILE__))))
FastGettext.locale = GettextSetup.negotiate_locale(GettextSetup.candidate_locales)

include Razor::CLI::Format

def die(message = nil)
  puts _("Error: %{error}") % {error: message} if message
  exit 1
end

begin
  parse = Razor::CLI::Parse.new(ARGV)
rescue Razor::CLI::InvalidURIError => e
  die e.message
rescue OptionParser::InvalidOption => e
  die _("%{error}\nTry 'razor --help' for more information") % {error: e.message}
end

if parse.show_version?
  version, exit_code = parse.version
  puts version
  exit exit_code
end

if parse.show_help? and not parse.show_command_help?
  output, exitcode = parse.help
  puts output
  exit exitcode
end

def unexpected_error(e)
  die _(<<-ERROR) % {backtrace: e.backtrace.take(10).join("\n"), error: e}
An unexpected error has occurred.

Backtrace:
  %{backtrace}

Error: %{error}

Please inspect server logs for the cause, then report issue to:
https://tickets.puppetlabs.com/browse/RAZOR

  ERROR
end

begin
  document = parse.navigate.get_document
  url = parse.navigate.last_url
  result = format_document document, parse
  # TRANSLATORS: This is a template for all results that the client outputs.
  puts _("From %{url}:\n\n%{result}\n\n") % {url: url, result: result}
rescue OptionParser::InvalidOption => e
  # TRANSLATORS: This occurs when invalid flags are passed in the navigation.
  die _("%{error}\nTry 'razor --help' for more information") %
      {error: e.message}
rescue SocketError, Errno::ECONNREFUSED => e
  puts _("Error: Could not connect to the server at %{url}\n" +
         "       %{error}") % {url: parse.api_url, error: e}
  die
rescue RestClient::SSLCertificateNotVerified
  puts _("Error: SSL certificate could not be verified against known CA " +
         "certificates.\n       To turn off verification, use the -k or --insecure option.")
  die
rescue RestClient::Exception => e
  r = e.response
  unexpected_error(e) if r.nil?
  request_type = r.args[:method].to_s.upcase
  url = r.args[:url]
  puts _("Error from doing %{request_type} %{url}") % {request_type: request_type, url: url}
  puts e.message
  begin
    body = MultiJson::load(r.body)
    puts body.delete("details") if body["details"]
    unless body.empty?
      puts format_document(body)
    end
  rescue => e
    # Ignore errors here; our best efforts at telling the user more about
    # what happened has failed. Just dump the response
    puts r.body
  end
  die
rescue StandardError => e
  die _("%{error}\nTry 'razor --help' for more information\n\n") % {error: e.message}
end
