#!/usr/bin/env ruby

require 'rhc/coverage_helper'

require 'rhc-common'

RHC::Helpers.deprecated_command('rhc app create',true)

def p_usage(error_code = 255)
    libra_server = get_var('libra_server')
    rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
    type_keys = RHC::get_cartridge_listing(nil, ', ', libra_server, RHC::Config.default_proxy, 'standalone', false)
    puts <<USAGE

Usage: #{$0}
Create an OpenShift app.

  -a|--app   application     Application name  (alphanumeric - max #{RHC::APP_NAME_MAX_LENGTH} chars) (required)
  -t|--type  type            Type of app to create (#{type_keys}) (required)
  -g|--gear-size size        The size of the gear for this app ([small|medium], defaults to small)
  -s|--scaling               Enable scaling for this app
  -l|--rhlogin  rhlogin      OpenShift login (#{rhlogin})
  -p|--password  password    Password (optional, will prompt)
  -r|--repo  path            Git Repo path (defaults to ./$app_name)
  -n|--nogit                 Only create remote space, don't pull it locally
  -d|--debug                 Print Debug info
  -h|--help                  Show Usage info
  --no-dns                   Skip DNS check. Must be used in combination with --nogit
  --config  path             Path of alternate config file
  --timeout #                Timeout, in seconds, for the session
  --enable-jenkins [name]    Create a Jenkins application (see Note 1)

Notes:
1. Jenkins applications will have Jenkins embedded.  Their default name will be 'jenkins' if not specified and the '--no-dns' flag is ignored.

USAGE
exit error_code
end

begin
    opts = GetoptLong.new(
        ["--debug", "-d", GetoptLong::NO_ARGUMENT],
        ["--help",  "-h", GetoptLong::NO_ARGUMENT],
        ["--no-dns", GetoptLong::NO_ARGUMENT],
        ["--nogit", "-n", GetoptLong::NO_ARGUMENT],
        ["--rhlogin",  "-l", GetoptLong::REQUIRED_ARGUMENT],
        ["--password",  "-p", GetoptLong::REQUIRED_ARGUMENT],
        ["--app",   "-a", GetoptLong::REQUIRED_ARGUMENT],
        ["--repo",  "-r", GetoptLong::REQUIRED_ARGUMENT],
        ["--config", GetoptLong::REQUIRED_ARGUMENT],
        ["--type",  "-t", GetoptLong::REQUIRED_ARGUMENT],
        ["--gear-size", "-g", GetoptLong::REQUIRED_ARGUMENT],
        ["--timeout", GetoptLong::REQUIRED_ARGUMENT],
        ["--enable-jenkins", GetoptLong::OPTIONAL_ARGUMENT],
        ["--scaling", "-s", GetoptLong::OPTIONAL_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')

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

opt['rhlogin'] = get_var('default_rhlogin') unless opt['rhlogin']

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

if !RHC::check_app(opt['app'])
    p_usage
end

if !opt['type']
    puts 'Type is required'
    p_usage
end

if !opt['rhlogin'] || !opt['app'] || !opt['type']
    p_usage
end

# Default gear size is small
gear_size = opt['gear-size']
gear_size = 'small' if !gear_size


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

user_info = RHC::get_user_info(libra_server, opt['rhlogin'], password, RHC::Config.default_proxy, false)
app_info = user_info['app_info']

if app_info[opt['app']]
  puts "An application named '#{opt['app']}' in namespace '#{user_info['user_info']['domains'][0]['namespace']}' already exists"
  exit 255
end

jenkins_app_name = nil
has_jenkins = false
if opt['enable-jenkins']
  app_info.each do |app_name, app|
    if app['framework'] == 'jenkins-1.4'
      jenkins_app_name = app_name
      has_jenkins = true
      puts "
Found existing Jenkins application: #{jenkins_app_name}
"
      if !opt['enable-jenkins'].empty?
        puts "Ignoring specified Jenkins app name: #{opt['enable-jenkins']}"
      end
    end
  end
  if !has_jenkins
    if opt['type'] =~ /^jenkins-/
      has_jenkins = true
      if opt['no-dns']
        puts "
The --no-dns option can't be used in conjunction with --enable-jenkins 
when creating a #{opt['type']} application.  Either remove the --no-dns
option or first install your #{opt['type']} application with --no-dns
and then use rhc-ctl-app to embed the Jenkins client. 
"
        exit 255
      end
      jenkins_app_name = opt['app']
      puts "
The Jenkins client will be embedded into the Jenkins application 
currently being created: '#{opt['app']}'
"
    end
  end
  if !has_jenkins
    if !opt['enable-jenkins'].empty?
      jenkins_app_name = opt['enable-jenkins']
    else
      jenkins_app_name = 'jenkins'
    end
  
    if !RHC::check_app(jenkins_app_name)
        p_usage
    end

    if jenkins_app_name == opt['app']
      puts "You must specify a different name for your application and Jenkins ('#{opt['app']}')."
      exit 100
    end
  
    if app_info.has_key?(jenkins_app_name)
      puts "You already have an application named '#{jenkins_app_name}'."
      puts "In order to continue you'll need to specify a different name"
      puts "with --enable-jenkins or destroy the existing application."
      exit 100
    end
  end
end

opt['repo'] = opt['app'] unless opt['repo']

if @mydebug
  puts "
  Found a bug? Post to the forum and we'll get right on it.
      IRC: #openshift on freenode
      Forums: https://openshift.redhat.com/community/forums/openshift
  
  "
end

#
# Confirm local git repo exists
#
unless opt['nogit']
    if File.exists?(opt['repo'])
        puts "We will not overwrite an existing git repo. Please remove:"
        puts "  #{File.expand_path(opt['repo'])}"
        puts "Then try again."
        puts
        exit 210
    else
        begin
            # Create the parent directory for the git repo
            @git_parent = File.expand_path(opt['repo'] + "/../")
            FileUtils.mkdir_p(@git_parent)
        rescue Exception => e
            puts "Could not write to #{@git_parent}"
            puts "Reason: #{e.message}"
            puts
            puts "Please re-run from a directory you have write access to or specify -r with a"
            puts "path you have write access to"
            puts
            exit 211
        end
    end
end

if jenkins_app_name && !has_jenkins
  jenkins_app = RHC::create_app(libra_server, RHC::Config.default_proxy, user_info, jenkins_app_name, 'jenkins-1.4', opt['rhlogin'], password, nil, false, true, true)
  available = RHC::check_app_available(RHC::Config.default_proxy, jenkins_app[:app_name], jenkins_app[:fqdn], jenkins_app[:health_check_path], jenkins_app[:result], jenkins_app[:git_url], nil, true)
  if !available
    puts "Unable to access your new Jenkins application."
    exit 1
  end
end

#
# Create remote application space
#
main_app = RHC::create_app(libra_server, RHC::Config.default_proxy, user_info, opt['app'], opt['type'], opt['rhlogin'], password, opt['repo'], opt['no-dns'], opt['nogit'], false, gear_size, opt['scaling'])

if !main_app
  puts "Create app failed"
  exit 1
end

if jenkins_app_name
  puts "Now embedding the jenkins client into '#{opt['app']}'..."
  RHC::ctl_app(libra_server, RHC::Config.default_proxy, opt['app'], opt['rhlogin'], password, 'configure', true, 'jenkins-client-1.4', nil, false)
end

unless opt['no-dns']
  available = RHC::check_app_available(RHC::Config.default_proxy, main_app[:app_name], main_app[:fqdn], main_app[:health_check_path], main_app[:result], main_app[:git_url], opt['repo'], opt['nogit'])
  if !available
    puts "Unable to access your new application."
    exit 1
  end
end
