#!/usr/bin/env oo-ruby
#--
# Copyright 2010 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#++

def usage
  puts <<USAGE
== Synopsis

#{$0}: Coordinate modifying the set of frontend http plugins on the node
  This command must be run as root.

== Usage

Changing the set of http plugins requires special steps in order to
preserve existing applications.

Those steps are:
#{$0} --save > file
#{$0} --delete
remove/install packages as needed
modify customized httpd configuration as needed and restart
edit /etc/openshift/node.conf
service ruby193-mcollective restart
#{$0} --restore < file


To save the http frontend configuration to a file:
#{$0} --save > file

To delete the existing http frontend configurations:
#{$0} --delete

To reload the http frontend configuration from a file:
#{$0} --restore < file

To rebuild the http frontend configuration from configured gears (does
not rebuild aliases or idler state):
#{$0} --rebuild

== List of additional arguments
     --confirm                          Do not ask before a dangerous operation
  -d|--debug                            Enable debug mode
  -h|--help                             Print this message

USAGE
  exit(255)
end

require 'rubygems'
require 'highline/import'
require 'openshift-origin-node'
opts = GetoptLong.new(
    ["--save",                      GetoptLong::NO_ARGUMENT],
    ["--delete",                    GetoptLong::NO_ARGUMENT],
    ["--confirm",                   GetoptLong::NO_ARGUMENT],
    ["--restore",                   GetoptLong::NO_ARGUMENT],
    ["--rebuild",                   GetoptLong::NO_ARGUMENT],
    ["--debug",               "-d", GetoptLong::NO_ARGUMENT],
    ["--help",                "-h", GetoptLong::NO_ARGUMENT]
)

mode = "help"
confirmed = false

begin
  opts.each do |k, v|
    case k
    when '--help'
      usage
    when '--save'
      mode = 'save'
    when '--delete'
      mode = 'delete'
    when '--restore'
      mode = 'restore'
    when '--rebuild'
      mode = 'rebuild'
    when '--confirm'
      confirmed = true
    when '--debug'
      $oo_debug = true
    else
      usage
    end
  end
rescue GetoptLong::Error => e
  usage
end

begin
  case mode

  when 'save'
    frontends = ::OpenShift::Runtime::FrontendHttpServer.all.to_a
    $stderr.puts("Backing up #{frontends.length} frontends.")
    $stdout.puts(JSON.pretty_generate(frontends))

  when 'delete'
    if confirmed or agree('Delete all web frontend configuration? (yes/no)')
      ::OpenShift::Runtime::FrontendHttpServer.all.each do |f|
        f.destroy
      end
    end

  when 'restore'
    JSON.load($stdin.read)

  when 'rebuild'
    if confirmed or agree('Rebuild all web frontend configurations? (yes/no)')
      ::OpenShift::Runtime::ApplicationContainer.all.each do |container|
        ::OpenShift::Runtime::FrontendHttpServer.new(container).create
        final_carts = []
        container.cartridge_model.each_cartridge do |cart|
          if cart.web_proxy?
            final_carts << cart
          else
            begin
              container.cartridge_model.connect_frontend(cart, true)
            rescue Exception => e
              $stderr.puts("ERROR: Failed to rebuild frontend for gear: #{container.name} cart: #{cart.name}")
              $stderr.puts("ERROR: #{e.message}")
              $stderr.puts(e.backtrace) if $oo_debug
            end
          end
        end

        final_carts.each do |cart|
          begin
            container.cartridge_model.connect_frontend(cart, true)
          rescue Exception => e
            $stderr.puts("ERROR: Failed to rebuild frontend for gear: #{container.name} cart: #{cart.name}")
            $stderr.puts("ERROR: #{e.message}")
            $stderr.puts(e.backtrace) if $oo_debug
          end
        end

      end
    end

  else
    usage
  end
rescue Exception => e
  $stderr.puts(e.message)
  $stderr.puts(e.backtrace) if $oo_debug or $oo_verbose
  exit(-1)
end
exit(0)

