#!/usr/bin/env ruby

require 'rhc/coverage_helper'

require 'rhc-common'

RHC::Helpers.deprecated_command('rhc domain (create|update)',true)

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

Usage: #{$0}
Bind a registered rhcloud user to a domain in rhcloud.

  NOTE: to change ssh key, alter your openshift <id_rsa> and
        <id_rsa>.pub keys, then re-run with --alter

  -n|--namespace   namespace   Namespace for your application(s) (alphanumeric - max #{RHC::DEFAULT_MAX_LENGTH} chars) (required)
  -l|--rhlogin     rhlogin     OpenShift login (#{rhlogin})
  -p|--password    password    Password (optional, will prompt)
  -a|--alter                   Alter namespace (will change urls) and/or ssh key
  -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

begin
    opts = GetoptLong.new(
        ["--debug", "-d", GetoptLong::NO_ARGUMENT],
        ["--help",  "-h", GetoptLong::NO_ARGUMENT],
        ["--rhlogin",  "-l", GetoptLong::REQUIRED_ARGUMENT],
        ["--password",  "-p", GetoptLong::REQUIRED_ARGUMENT],
        ["--namespace", "-n", GetoptLong::REQUIRED_ARGUMENT],
        ["--config", GetoptLong::REQUIRED_ARGUMENT],
        ["--alter", "-a", GetoptLong::NO_ARGUMENT],
        ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
    )
    
    opt = {}
    opts.each do |o, a|
        opt[o[2..-1]] = a.to_s
    end
rescue Exception => e
  #puts e.message
  p_usage
end

# 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']

ssh_key_file_path = get_kfile(false)
ssh_pub_key_file_path = get_kpfile(ssh_key_file_path, opt['alter'])

ssh_config = "#{ENV['HOME']}/.ssh/config"
ssh_config_d = "#{ENV['HOME']}/.ssh/"

p_usage 0 if opt["help"]
p_usage if 0 != ARGV.length


debug = true if opt["debug"]

RHC::debug(debug)

RHC::timeout(opt["timeout"], get_var('timeout'))
RHC::connect_timeout(opt["timeout"], get_var('timeout'))

if !RHC::check_namespace(opt['namespace'])
    p_usage
end

if !RHC::check_rhlogin(opt['rhlogin'])
    p_usage
end


if !opt["rhlogin"] || !opt["namespace"]
    p_usage
end

password = opt['password']
if !password
  password = RHC::get_password
end

#
# Check to see if a ssh_key_file_path exists, if not create it.
#

if File.readable?(ssh_key_file_path)
    puts "OpenShift key found at #{ssh_key_file_path}.  Reusing..."
else
    puts "Generating OpenShift ssh key to #{ssh_key_file_path}"
    # Use system for interaction
    system("ssh-keygen -t rsa -f '#{ssh_key_file_path}'")
end

ssh_keyfile_contents = File.open(ssh_pub_key_file_path).gets.chomp.split(' ')
ssh_key = ssh_keyfile_contents[1]
ssh_key_type = ssh_keyfile_contents[0]

data = {'namespace' => opt['namespace'],
        'rhlogin' => opt['rhlogin'],
        'ssh' => ssh_key,
        'key_type' => ssh_key_type}

if (opt['alter'])
  data[:alter] = true
  not_found_message = "A user with rhlogin '#{opt['rhlogin']}' does not have a registered domain.  Be sure to run rhc-create-domain without -a|--alter first."
  user_info = RHC::get_user_info(libra_server, opt['rhlogin'], password, RHC::Config.default_proxy, true, not_found_message)
end
if debug
  data[:debug] = true
end
RHC::print_post_data(data)
json_data = RHC::generate_json(data)

url = URI.parse("https://#{libra_server}/broker/domain")
response = RHC::http_post(RHC::Config.default_proxy, url, json_data, password)

if response.code == '200'
    begin
        json_resp = RHC::json_decode(response.body)
        RHC::print_response_success(json_resp)
        if opt['alter'] != ''
            puts <<EOF
Creation successful

You may now create an application.

EOF
        else
            app_info = user_info['app_info']
            dns_success = true
            if !app_info.empty? && opt['namespace'] != user_info['user_info']['domains'][0]['namespace']
              #
              # Confirm that the host(s) exist in DNS
              #
              puts "Now your new domain name(s) are being propagated worldwide (this might take a minute)..."
              # Allow DNS to propogate
              sleep 15
              app_info.each_key do |appname|
                  fqdn = "#{appname}-#{opt['namespace']}.#{user_info['user_info']['rhc_domain']}"
                  
                  # Now start checking for DNS
                  loop = 0
                  sleep_time = 2
                  while loop < RHC::MAX_RETRIES && !RHC::hostexist?(fqdn)
                      sleep sleep_time
                      loop+=1
                      puts "  retry # #{loop} - Waiting for DNS: #{fqdn}"
                      sleep_time = RHC::delay(sleep_time)
                  end
                  
                  if loop >= RHC::MAX_RETRIES
                      puts "Host could not be found: #{fqdn}"
                      dns_success = false
                  end
              end
              puts "You can use rhc-domain-info to view any url changes.  Be sure to update any links"
              puts "including the url in your local git config: <local_git_repo>/.git/config"
            end
            if dns_success
              puts "Alteration successful."
            else
              puts "Alteration successful but at least one of the urls is still updating in DNS."
            end
            puts ""
        end
        exit 0
    rescue RHC::JsonError
        RHC::print_response_err(response)
    end
else
    RHC::print_response_err(response)
end
exit 1
