#!/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_relative "../lib/razor/cli"

include Razor::CLI::Format

def die(message = nil)
  puts "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 e.message + "\nTry 'razor --help' for more information"
end

if parse.show_version?
  puts parse.version
  exit 0
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
An unexpected error has occurred.

Backtrace:
  #{e.backtrace.take(10).join('
  ')}

Error: #{e}

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
  puts "From #{url}:\n\n#{format_document document, parse}\n\n"
rescue OptionParser::InvalidOption => e
  # Occurs when invalid flags are passed in the navigation.
  die e.message + "\nTry 'razor --help' for more information"
rescue SocketError, Errno::ECONNREFUSED => e
  puts "Error: Could not connect to the server at #{parse.api_url}"
  puts "       #{e}\n"
  die
rescue RestClient::SSLCertificateNotVerified
  puts "Error: SSL certificate could not be verified against known CA certificates."
  puts "       To turn off verification, use the -k or --insecure option."
  die
rescue RestClient::Exception => e
  r = e.response
  unexpected_error(e) if r.nil?
  puts "Error from doing #{r.args[:method].to_s.upcase} #{r.args[: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 "#{e.message}\nTry 'razor --help' for more information\n\n"
end
