#!/usr/bin/env python

import argparse
import logging
import sys

FORMAT = '%(asctime)-15s %(levelname)s %(message)s'
logging.basicConfig(level=logging.INFO,
                    format=FORMAT,
                    #filename='out',
                    filemode='a'
                    )

import bellatrix
import bellatrix.bewitch_ami
import bellatrix.burn_instance
import bellatrix.copy2s3
import bellatrix.set_permissions
import bellatrix.set_security
import bellatrix.start_instance
import bellatrix.provision
import bellatrix.stop
import bellatrix.list


def bewitch(args):
    logging.info("bewitching...")
    sys.exit(bellatrix.bewitch_ami.run(args.configuration))

def copy2s3(args):
    logging.info("uploading to S3...")
    sys.exit(bellatrix.copy2s3.run(args.source, args.bucket, args.acl, args.key_prefix))

def burn(args):
    logging.info("burning...")
    sys.exit(bellatrix.burn_instance.run(args.instance, args.image_name, args.wait))

def perm2ami(args):
    logging.info("applying permissions to ami...")
    sys.exit(bellatrix.set_permissions.run(args.ami, args.permissions_file))

def setsecurity(args):
    logging.info("applying restrictions to security group...")
    sys.exit(bellatrix.set_security.run(args.security_group_name, args.ports_file, args.ip_ranges_file))
    
def startinstance(args):
    logging.info("starting EC2 instance...")
    logging.info("ami:%s type:%s key_name:%s security_groups:%s new size:%s" % (args.ami, args.type, args.key_name, args.security_groups, args.new_size))
    sys.exit(bellatrix.start_instance.run(args.ami, args.type, args.key_name, args.security_groups, args.new_size))

def provision(args):
    logging.info("provisioning...")
    sys.exit(bellatrix.provision.run(args.configuration, args.user, args.hostname, args.private_key))

def stop(args):
    logging.info("stopping...")
    sys.exit(bellatrix.stop.stop(args.instance))

def terminate(args):
    logging.info("terminating...")
    sys.exit(bellatrix.stop.terminate(args.instance))

def list(args):
    logging.info("listing...")
    sys.exit(bellatrix.list.list())

#-------------------------------------------------------

def main():
    # create the base parser with a subparsers argument
    parser = argparse.ArgumentParser(prog=bellatrix.APP.lower(), \
                                    description=bellatrix.description)
    parser.add_argument('--version', action='version', version=bellatrix.APP + " " + bellatrix.__version__)
    subparsers = parser.add_subparsers()
    
    parser_bewitch = subparsers.add_parser('bewitch', help='Start a new instance, apply a configuration to it and finally save it into a new ami.')
    parser_bewitch.add_argument('configuration', help='Python configuration file. E.g. ubuntu.py')
    parser_bewitch.set_defaults(func=bewitch)

    parser_copy2s3 = subparsers.add_parser('copy2s3', help='Copy a file or directory to a S3 bucket.')
    parser_copy2s3.add_argument('source', help='Source file or directory.')
    parser_copy2s3.add_argument('bucket', help='S3 bucket destination. It must already exist.')
    parser_copy2s3.add_argument('key_prefix', help='This prefix will be added to the source path we copy. Blank by default.', \
    default='', nargs='?')
    parser_copy2s3.add_argument('acl', help='ACL policy for the new files in the S3 bucket. If you don''t specify anything ACL will be private by default.', \
    default='private', nargs='?', choices=['private', 'public-read', 'public-read-write', 'authenticated-read'])
    parser_copy2s3.set_defaults(func=copy2s3)

    parser_burn = subparsers.add_parser('burn', help='Burn a running instance into a new ami.')
    parser_burn.add_argument('instance', help='Instance name. Something like: i-b63c98d4 The instance should be running.')
    parser_burn.add_argument('image_name', help='Image name. A time stamp will be added to the image name.')
    parser_burn.add_argument('--wait', help='Wait until ami is ready to use.', \
    default=False, nargs='?', type=bool)
    parser_burn.set_defaults(func=burn)

    parser_perm2ami = subparsers.add_parser('perm2ami', help='Gives permissions to other accounts to launch your ami.')
    parser_perm2ami.add_argument('ami', help='AMI name. Something like ami-6ba27502')
    parser_perm2ami.add_argument('permissions_file', help='Text file with an account number (12 digits number without dashes) on each line.')
    parser_perm2ami.set_defaults(func=perm2ami)

    parser_set_security = subparsers.add_parser('set_security', help='Apply restrictions to a security group. EC2 instances run under a security group. They allow you to apply restrictions like open ports of ip ranges that can connect to the instances.')
    parser_set_security.add_argument('security_group_name', help='Name of the security group.')
    parser_set_security.add_argument('ports_file', help='Text file with a list of ports (one on each line) that will be opened. You can comment lines with # or have blank lines.')
    parser_set_security.add_argument('ip_ranges_file', help='Text file with a list of ip ranges (one on each line) that will be allowed to connect to your EC2 instances.')
    parser_set_security.set_defaults(func=setsecurity)

    parser_startinstance = subparsers.add_parser('start', help='Start a new EC2 instance.')
    parser_startinstance.add_argument('ami', help='AMI name. Something like ami-6ba27502')
    parser_startinstance.add_argument('key_name', 
    help='Name of the key-pair name that will be applied to your instance. The key pair is a group of two files, the public one in the instance and the private one in your computer that will help you connecting to your instance using: ssh -i private_key user@public_dns')
    parser_startinstance.add_argument('--security_groups',help='comma separated list (with no spaces) of the security groups that will be applied to the new instance. It can be only one. By default it will be "default"',
    default='default', nargs='?')
    parser_startinstance.add_argument('--type', help='instance type. t1.micro by default. Please take a look at: http://aws.amazon.com/ec2/instance-types for more info.', 
    choices=['m1.small', 'm1.large', 'm1.xlarge', 't1.micro', 'm2.xlarge', 'm2.2xlarge', 'm2.4xlarge', 'c1.medium', 'c1.xlarge', 'cc1.4xlarge', 'cc2.8xlarge'], 
    default='t1.micro', nargs='?')
    parser_startinstance.add_argument('--new_size',
    help="""Overrides default size (in giga bytes) of the EBS volume.""",
    default=None, nargs='?', type=int)
    parser_startinstance.set_defaults(func=startinstance)

    parser_provision = subparsers.add_parser('provision', help='Apply a configuration to a running machine (EC2 or not).')
    parser_provision.add_argument('configuration', help='Python configuration file. E.g. ubuntu.py')
    parser_provision.add_argument('user', help='User used to connect to the machine E.g. ubuntu')
    parser_provision.add_argument('hostname', help='Hostname or simply the ip of the machine.')
    parser_provision.add_argument('--private_key', help='In case we need to specify a private key to connect to the host. This is empty by default',
    default='', nargs='?')
    parser_provision.set_defaults(func=provision)

    parser_stop = subparsers.add_parser('stop', help='Stop a given instance or all of them if you pass the "all" argument. Stopping an instance will shut-down the instance but preserve data on the EBS volume. After stopping you will only be charged $0.10 per allocated GB per month (http://aws.amazon.com/ebs/).')
    parser_stop.add_argument('instance', help='Instance id. Something like i-39e2075d. If you pass "all" then all instances will be stopped.')
    parser_stop.set_defaults(func=stop)

    parser_terminate = subparsers.add_parser('terminate', help='Terminate a given instance or all of them if you pass the "all" parameter. Terminating an instance will shut it down and delete data on the EBS volume. Your instance/s won''t produce any cost after you terminate them.')
    parser_terminate.add_argument('instance', help='Instance id. Something like i-39e2075d. If you pass ALL then all instances will be terminated (unless they are explicitly protected)')
    parser_terminate.set_defaults(func=terminate)

    parser_list = subparsers.add_parser('list', help='List all your EC2 instances.')
    parser_list.set_defaults(func=list)

    args = parser.parse_args()
    args.func(args)

if __name__ == "__main__":
    main()
