#!/usr/bin/env ruby
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.  The
# ASF licenses this file to you 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.

require 'rubygems'
require 'optparse'
require 'uri'
require 'deltacloud'
require 'plain_formatter'

include DeltaCloud::PlainFormatter

options = {
  :verbose => false
}

@optparse = OptionParser.new do |opts|

opts.banner = <<BANNER
Usage:
deltacloudc collection operation [options]

URL format:
API_URL=http://[user]:[password]@[api_url][port][/uri]
  OR 
API_URL=http://[api_url][port][/uri] with -U and -P for credentials

Examples:

 1. To list collections for deltacloud api on port 3333 of server deltacloud.foo

        deltacloudc -l -u http://user:password@deltacloud.foo:3333/api

 2. To list the operations for the 'images' collection:

        deltacloudc images -l -U username -P password -u http://deltacloud.foo:3333/api

 3. To list all images (i.e. call the 'index' operation of 'images'):

        deltacloudc images index -u http://user:password@deltacloud.foo:3333/api

 4. To get the details of image '5':

        deltacloudc images show -i 5 -U username -P password -u http://deltacloud.foo:3333/api

Options:
BANNER
  opts.on( '-i', '--id ID', 'ID for operation') { |id| options[:id] = id }
  opts.on( '-d', '--image-id ID', 'Image ID') { |id| options[:image_id] = id }
  opts.on( '-b', '--bucket-id ID', 'Bucket ID') {|id| options[:bucket_id] = id }
  opts.on( '-r', '--bucket-location NAME', 'Bucket location') {|name| options[:bucket_location] = name }
  opts.on( '-a', '--arch ARCH', 'Architecture (x86, x86_64)') { |id| options[:architecture] = id }
  opts.on( '-p', '--hardware-profile HARDWARE_PROFILE', 'Hardware Profile') { |id| options[:hwp_id] = id }
  opts.on( '-n', '--name NAME', 'Name (for instance eg.)') { |name| options[:name] = name }
  opts.on( '-s', '--state STATE', 'Instance state (RUNNING, STOPPED)') { |state| options[:state] = state }
  opts.on( '-u', '--url URL', 'API url ($API_URL variable)') { |url| options[:api_url] = url }
  opts.on( '-U', '--user USER', 'API username ($API_USERNAME variable)') { |u| options[:api_user] = u }
  opts.on( '-P', '--password PASSWORD', 'API password ($API_PASSWORD variable)') { |p| options[:api_password] = p }
  opts.on( '-l', '--list', 'List collections/operations') { |id| options[:list] = true }
  opts.on( '-h', '--help', 'Display this screen' ) { puts @optparse; Kernel.exit! }
  opts.on( '-v', '--version', 'Display API version' ) { options[:version]=true }
  opts.on( '-V', '--verbose', 'Print verbose messages' ) { options[:verbose]=true }
  opts.on( '-f', '--file-path PATH', 'local path for new blob data') {|path| options[:file_path]=path }
  opts.on( '-m', '--blob-metadata k1=v1, k2=v2', 'Comma seperated k=v pairs for blob metadata (for create operation)') do |meta|
                    blob_meta = {}
                    meta.gsub!(/ /,"")
                    meta.scan(/(\w+)=(\w+)/).map {|k,v| blob_meta[k] = v }
                    options[:blob_metadata] = blob_meta
                end
end

def invalid_usage(error_msg='')
  puts "\n ERROR: #{error_msg} \n\n"
  puts @optparse
  exit(1)
end

begin
    @optparse.parse!
rescue Exception => e
    invalid_usage(e.message)
end

# First try to get API_URL from environment
options[:api_url] = ENV['API_URL'] if options[:api_url].nil?

if(options[:api_url].nil?)
    invalid_usage("You must supply the url to the deltacloud api; either use '-u' flag or set the 'API_URL' environment variable")
end

url = URI.parse(options[:api_url])
api_url = "http://#{url.host}#{url.port ? ":#{url.port}" : ''}#{url.path}"

options[:collection] = ARGV[0]
options[:operation] = ARGV[1]

# Connect to Deltacloud API and fetch all entry points
client = DeltaCloud.new(options[:api_user] || url.user || ENV['API_USER'], options[:api_password] || url.password || ENV['API_PASSWORD'], api_url)
collections = client.entry_points.keys

# Exclude collection which don't have methods in client library yet
collections.delete(:instance_states)
#add blob collection if buckets is present
collections << :blob if collections.include?(:buckets)

# If list parameter passed print out available collection
# with API documentation
if options[:list] and options[:collection].nil?
  collections.each do |c|
    puts sprintf("%-22s", c.to_s[0, 22])
  end
  exit(0)
end

# If collection parameter is present and user requested list
# print all operation defined for collection with API documentation
if options[:list] and options[:collection]
  #deal with blobs again - bypass 'normal' docs procedure
  if options[:collection] =~ /blob/i
    puts "create \t\t: Create a new blob in a specified bucket (POST /api/buckets/:bucket)"
    puts "destroy \t: Delete a specified blob in a specified bucket (DELETE /api/buckets/:bucket/:blob)"
    puts "show \t\t: Get details of a specified blob in a specified bucket (GET /api/buckets/:bucket/:blob)"
    puts "data \t\t: Get the contents of a specified blob - the blob data content itself"
    exit(0)
  end
  doc = client.documentation(options[:collection])
  doc.operations.each do |c|
    puts sprintf("%-20s: %s", c.operation, c.description)
  end
  exit(0)
end

if options[:version]
  puts "Deltacloud API(#{client.driver_name}) 0.1"
  exit(0)
end

# List items from collection (typically /instances)
# Do same if 'index' operation is set
if options[:collection] and ( options[:operation].nil? or options[:operation].eql?('index') )
  invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
#cannot list blobs - can only show a specific blob
  invalid_usage("You must specify a particular blob with -i and a particular bucket with -b") if options[:collection] =~ (/blob/i)
  params = {}
  params.merge!(:architecture => options[:architecture]) if options[:architecture]
  params.merge!(:id => options[:id]) if options[:id]
  params.merge!(:state => options[:state]) if options[:state]
  client.send(options[:collection].to_s, params).each do |model|
    puts format(model)
  end
  exit(0)
end

if options[:collection] and options[:operation]

  invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)

  params = {}
  params.merge!(:id => options[:id]) if options[:id]

  # If collection is set and requested operation is 'show' just 'singularize'
  # collection name and print item with specified id (-i parameter)
  #Blobs are a special case so deal with first -
  if options[:collection] =~ (/blob/i)
    invalid_usage("Please specify the bucket for this blob using the -b option") unless options[:bucket_id]
    invalid_usage("Missing blob ID, please specify with -i option") unless options[:id]
    params = {}
    params.merge!(:id => options[:id], 'bucket' => options[:bucket_id])
    params.merge!('metadata'=>options[:blob_metadata]) unless options[:blob_metadata].nil?
    case options[:operation]
        when 'show' then puts format(client.send( options[:collection], params))
        when 'data' then puts client.blob_data(params)
        when 'create' then
            invalid_usage("Specify the location of the new blob data (full local path) using -f option") unless options[:file_path]
            params.merge!('file_path'=>options[:file_path])
            blob = client.create_blob(params)
            puts format(blob)
        when 'destroy' then client.destroy_blob(params)
        else invalid_usage("Please specify a valid operation for the blob collection - try -l to see available operations")
    end
    exit(0)
  end

  if options[:operation].eql?('show')
    invalid_usage("Missing ID, must be provided with --id") unless options[:id]
    puts format(client.send(options[:collection].gsub(/s$/, ''), options[:id]))
    exit(0)
  end

  # If collection is set and requested operation is create new instance,
  # --image-id, --hardware-profile and --name parameters are used
  # Returns created instance in plain form
  if options[:collection].eql?('instances') and options[:operation].eql?('create')
    invalid_usage("Missing image-id") unless options[:image_id]
    if options[:name] and ! client.feature?(:instances, :user_name)
      invalid_usage("Driver does not support user-supplied name")
    end
    params.merge!(:name => options[:name]) if options[:name]
    params.merge!(:image_id => options[:image_id]) if options[:image_id]
    params.merge!(:hwp_id => options[:hwp_id]) if options[:hwp_id]
    instance = client.create_instance(options[:image_id], params)
    puts format(instance)
    exit(0)
  end

  #Create and Destroy a bucket - require the bucket id:
  if options[:collection].eql?('buckets')
    if options[:operation].eql?('create')
        invalid_usage("Please specify an id for the new bucket with -i") unless options[:id]
        bucket = client.create_bucket('id'=>options[:id], 'bucket_location'=>options[:bucket_location])
        puts format(bucket)
    elsif options[:operation].eql?('destroy')
        invalid_usage("Please specify the bucket you wish to destroy with -i") unless options[:id]
        client.destroy_bucket('id'=>options[:id])
    else
        invalid_usage("Please specify a valid operation on buckets - use -l to see valid operations")
    end
    exit(0)
  end

  # All other operations above collections is done there:
  if options[:collection].eql?('instances')
    instance = client.instance(options[:id])
    instance.send("#{options[:operation]}!".to_s)
    instance = client.instance(options[:id])
    puts format(instance)
    exit(0)
  end
end

# If all above passed (eg. no parameters)
puts @optparse
