#!/usr/bin/env ruby
# Copyright 2011 Red Hat, Inc.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

require 'rhc-common'

embed_mapper = { 'add' => 'configure', 'remove' => 'deconfigure' }

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

Usage: #{$0}
Control an OpenShift express app

  -a|--app   application   Application name  (alphanumeric) (required)
  -l|--rhlogin rhlogin     Red Hat login (RHN or OpenShift login with OpenShift Express access) (#{rhlogin})
  -p|--password password   RHLogin password  (optional, will prompt)
  -c|--command command     (start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias|threaddump)
  -L|--embedded-list       List supported embedded cartridges
  -e|--embed               (add|remove|stop|start|restart|status|reload)-$cartridge eg: add-mysql-5.1
  -b|--bypass              Bypass warnings
  -d|--debug               Print Debug info
  -h|--help                Show Usage info
  --alias                  Specify server alias (when using add/remove-alias)
  --config  path           Path of alternate config file
  --timeout #              Timeout, in seconds, for connection

USAGE
exit 255
end

def p_embedded_list
    libra_server = get_var('libra_server')
    puts ""
    puts "List of supported embedded cartridges:"
    puts ""
    type_keys = RHC::get_cartridge_listing(nil, ', ', libra_server, @http, 'embedded', false)
    puts type_keys
    puts ""
    exit 255
end

begin
    opts = GetoptLong.new(
        ["--debug",     "-d", GetoptLong::NO_ARGUMENT],
        ["--help",      "-h", GetoptLong::NO_ARGUMENT],
        ["--bypass",    "-b", GetoptLong::NO_ARGUMENT],
        ["--embedded-list",   "-L", GetoptLong::NO_ARGUMENT],
        ["--rhlogin",    "-l", GetoptLong::REQUIRED_ARGUMENT],
        ["--embed",      "-e", GetoptLong::REQUIRED_ARGUMENT],
        ["--password",   "-p", GetoptLong::REQUIRED_ARGUMENT],
        ["--app",        "-a", GetoptLong::REQUIRED_ARGUMENT],
        ["--alias",      GetoptLong::REQUIRED_ARGUMENT],
        ["--config", GetoptLong::REQUIRED_ARGUMENT],
        ["--command",    "-c", GetoptLong::REQUIRED_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
check_cpath(opt)

# Pull in configs from files
libra_server = get_var('libra_server')
debug = get_var('debug') == 'false' ? nil : get_var('debug')
ssh_config = "#{ENV['HOME']}/.ssh/config"
ssh_config_d = "#{ENV['HOME']}/.ssh/"

if opt["embedded-list"]
    p_embedded_list
end
if opt["help"]
    p_usage
end

if opt["debug"]
    debug = true
end
RHC::debug(debug)

RHC::timeout(opt["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

unless opt["embed"] or opt["command"]
    puts "Command or embed is required"
    p_usage
end

if opt["command"]
  unless opt["command"] =~ /^(start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias|threaddump)$/
    puts "Invalid command '#{opt["command"]}' specified.  Valid commands are (start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias|threaddump)"
    p_usage
  end
elsif opt["embed"]
  action = opt['embed'].split('-')[0]
  unless action =~ /^(add|remove|start|stop|restart|status|reload)$/
    puts "Invalid embed action '#{action}' specified.  Valid embed actions are (add|remove|start|stop|restart|status|reload)"
    p_usage
  end
end

unless opt['rhlogin'] && opt['app'] && (opt['command'] || opt['embed'])
    p_usage
end

if opt['command'] and (opt['alias'] and !(opt['command'] =~ /-alias$/)) || ((opt['command'] =~ /-alias$/) and ! opt['alias'])
    puts "When specifying alias make sure to use -c add-alias or -c remove-alias"
    p_usage
end

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

opt["command"] = "deconfigure" if opt["command"] == "destroy"

if !opt["bypass"] and opt["command"] == "deconfigure"
    # deconfigure is the actual hook called on 'destroy'
    # destroy is used for clarity


    puts <<WARNING
!!!! WARNING !!!! WARNING !!!! WARNING !!!!
You are about to destroy the #{opt['app']} application.

This is NOT reversible, all remote data for this application will be removed.
WARNING

    print "Do you want to destroy this application (y/n): "
    begin
      agree = gets.chomp
      if agree != 'y'
          puts "\n"
          exit 217
      end
    rescue Interrupt
      puts "\n"
      exit 217
    end
end

framework = nil
if opt['embed']
    action = opt['embed'].split('-')[0]
    # override action if it's in the mapper
    action = embed_mapper[opt['embed'].split('-')[0]] if embed_mapper[opt['embed'].split('-')[0]]
    framework = opt['embed'].split('-')[1..-1].join('-')
    url = URI.parse("https://#{libra_server}/broker/embed_cartridge")
else
    action = opt['command']
    url = URI.parse("https://#{libra_server}/broker/cartridge")
end

RHC::ctl_app(libra_server, @http, opt['app'], opt['rhlogin'], password, action, opt['embed'], framework, opt['alias'])
