#!/usr/bin/env ruby

require 'rhc/coverage_helper'

require 'rhc-common'

RHC::Helpers.deprecated_command('rhc sshkey',true)

#
# print help
#
def p_usage(exit_code = 255)
    rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
    puts <<USAGE

Usage: rhc sshkey (<command> | --help) [<args>]
Manage multiple keys for the registered rhcloud user.

List of commands
  list                           Display all the SSH keys for the user account
  add                            Add SSH key to the user account
  update                         Update SSH key for the user account
  remove                         Remove SSH key from the user account

List of arguments
  -l|--rhlogin      rhlogin      OpenShift login (#{rhlogin})
  -p|--password     password     Password (optional, will prompt)
  -i|--identifier   key-name     User-specified identifier for the key
  -k|--ssh          key-filepath SSH public key filepath 
  -d|--debug                     Print Debug info
  -h|--help                      Show Usage info
  --config          path         Path of alternate config file
  --timeout         #            Timeout, in seconds, for the session

USAGE
exit exit_code
end


def validate_args(val_id=true)
  # If provided a config path, check it
  RHC::Config.check_cpath($opt)
  
  # Pull in configs from files
  $libra_server = get_var('libra_server')
  debug = get_var('debug') == 'false' ? nil : get_var('debug')
  
  $opt['rhlogin'] = get_var('default_rhlogin') unless $opt['rhlogin']
  p_usage if !RHC::check_rhlogin($opt['rhlogin'])
  
  debug = $opt["debug"] ? true : false
  RHC::debug(debug)
  
  p_usage if val_id && !RHC::check_key($opt['identifier'])
  
  RHC::timeout($opt["timeout"], get_var('timeout'))
  RHC::connect_timeout($opt["timeout"], get_var('timeout'))
  $password = $opt['password'] ? $opt['password'] : RHC::get_password
end

def remove_key
  validate_args(true)

  data = {}
  data[:rhlogin] = $opt['rhlogin']
  data[:key_name] = $opt['identifier']
  data[:action] = 'remove-key'

  url = URI.parse("https://#{$libra_server}/broker/ssh_keys")
  handle_key_mgmt_response(url, data, $password)
end

def show_key_list
  validate_args(false)
  
  ssh_keys = RHC::get_ssh_keys($libra_server, $opt['rhlogin'], $password, RHC::Config.default_proxy)
  additional_ssh_keys = ssh_keys['keys']
  
  puts ""
  puts "SSH keys"
  puts "========"

  # first list the primary key
  puts "       Name: default"
  puts "       Type: #{ssh_keys['ssh_type']}"
  puts "Fingerprint: #{ssh_keys['fingerprint']}"
  #puts "        Key: #{ssh_keys['ssh_key']}"
  puts ""
    
  # now list the additional keys
  if additional_ssh_keys && additional_ssh_keys.kind_of?(Hash)
    additional_ssh_keys.each do |name, keyval|
      puts "       Name: #{name}"
      puts "       Type: #{keyval['type']}"
      puts "Fingerprint: #{keyval['fingerprint']}"
      #puts "        Key: #{keyval['key']}"
      puts ""
    end
  end
end

begin
  argv_c = ARGV.clone

  if ARGV[0] =~ /^(add|update)$/
    ARGV.shift
    opts = GetoptLong.new(
        ["--debug", "-d", GetoptLong::NO_ARGUMENT],
        ["--help", "-h", GetoptLong::NO_ARGUMENT],
        ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
        ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
        ["--identifier", "-i", GetoptLong::REQUIRED_ARGUMENT],
        ["--ssh", "-k", GetoptLong::REQUIRED_ARGUMENT],
        ["--config", GetoptLong::REQUIRED_ARGUMENT],
        ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
    )
  elsif ARGV[0] =~ /^remove$/
    ARGV.shift
    opts = GetoptLong.new(
        ["--debug", "-d", GetoptLong::NO_ARGUMENT],
        ["--help",  "-h", GetoptLong::NO_ARGUMENT],
        ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
        ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
        ["--identifier", "-i", GetoptLong::REQUIRED_ARGUMENT],
        ["--config", GetoptLong::REQUIRED_ARGUMENT],
        ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
    )
  elsif ARGV[0] =~ /^list$/
    ARGV.shift
    opts = GetoptLong.new(
        ["--debug", "-d", GetoptLong::NO_ARGUMENT],
        ["--help",  "-h", GetoptLong::NO_ARGUMENT],
        ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
        ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
        ["--config", GetoptLong::REQUIRED_ARGUMENT],
        ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
    )
  else
    opts = GetoptLong.new(
      ["--help",  "-h", GetoptLong::NO_ARGUMENT]
    )
    unless ARGV[0] =~ /^(help|-h|--help)$/
      puts "Missing or invalid command!"
      # just exit at this point
      # printing the usage description will be handled in the rescue
      exit 255
    end
  end

  $opt = {}
  opts.each do |o, a|
    $opt[o[2..-1]] = a.to_s
  end

rescue Exception => e
  p_usage
end

p_usage 0 if $opt["help"]

case argv_c[0]
when "add", "update"
  validate_args(true)
  add_or_update_key(argv_c[0], $opt['identifier'], $opt['ssh'],
                    $opt['rhlogin'], $password)
when "remove"
  remove_key
when "list", nil
  show_key_list
when "-h", "--help", "help", nil
  p_usage 0
else
  puts "Invalid command!"
  p_usage
end

exit 0
