# -*- coding: UTF-8 -*-
"""
Usage:
  leadbutt [options]

Options:
  -h --help                   Show this screen.
  -c FILE --config-file=FILE  Path to a YAML configuration file [default: config.yaml].
  -p INT --period INT         Period length, in minutes [default: 1]
  -n INT                      Number of data points to get [default: 5]
"""
from __future__ import unicode_literals

from calendar import timegm
import datetime
import sys

from docopt import docopt
import boto.ec2.cloudwatch
import yaml


# emulate six.text_type based on https://docs.python.org/3/howto/pyporting.html#str-unicode
if sys.version_info[0] >= 3:
    text_type = str
else:
    text_type = unicode


# configuration

DEFAULT_REGION = 'us-east-1'
DEFAULT_FORMAT = ('cloudwatch.%(Namespace)s.%(dimension)s.%(MetricName)s'
    '.%(Statistics)s.%(Unit)s')


def get_config(config_file):
    """Get configuration from a file."""
    def load(fp):
        try:
            return yaml.load(fp)
        except yaml.YAMLError as e:
            sys.stderr.write(text_type(e))  # XXX python3
            sys.exit(1)  # TODO document exit codes

    if config_file == '-':
        return load(sys.stdin)
    with open(config_file) as fp:
        return load(fp)


def output_results(results, metric):
    """
    Output the results to stdout.

    TODO: add AMPQ support for efficiency
    """
    options = metric.get('Options', {})
    formatter = options.get('Formatter', DEFAULT_FORMAT)
    context = metric.copy()
    try:
        context['dimension'] = list(metric['Dimensions'].values())[0]
    except AttributeError:
        context['dimension'] = ''
    for result in results:
        # get and then sanitize metric name
        metric_name = (formatter % context).replace('/', '.').lower()
        line = '{} {} {}\n'.format(
            metric_name,
            result[metric['Statistics']],
            timegm(result['Timestamp'].timetuple()),
        )
        sys.stdout.write(line)


def leadbutt(config_file, period, count, **kwargs):
    config = get_config(config_file)

    # TODO use auth from config if exists
    region = config.get('region', DEFAULT_REGION)
    conn = boto.ec2.cloudwatch.connect_to_region(region)
    for metric in config['metrics']:
        end_time = datetime.datetime.utcnow()
        start_time = end_time - datetime.timedelta(seconds=period * count)
        results = conn.get_metric_statistics(
            period,  # minimum: 60
            start_time,
            end_time,
            metric['MetricName'],  # RequestCount
            metric['Namespace'],  # AWS/ELB
            metric['Statistics'],  # Sum
            dimensions=metric['Dimensions'],
            unit=metric['Unit'],
        )
        output_results(results, metric)


def main(*args, **kwargs):
    options = docopt(__doc__)
    # help: http://boto.readthedocs.org/en/latest/ref/cloudwatch.html#boto.ec2.cloudwatch.CloudWatchConnection.get_metric_statistics
    config_file = options.pop('--config-file')
    period = int(options.pop('--period')) * 60
    count = int(options.pop('-n'))
    leadbutt(config_file, period, count, **options)


if __name__ == '__main__':
    main()

@@ -336,16 +336,54 @@
 ult: 5%5D%0A
+  -v                          Verbose%0A
 %22%22%22%0Afrom
@@ -2043,16 +2043,31 @@
 , count,
+ verbose=False,
  **kwarg
@@ -2200,16 +2200,81 @@
 REGION)%0A
+    connect_args = %7B%0A        'debug': 2 if verbose else 0,%0A    %7D%0A
     conn
@@ -2320,16 +2320,32 @@
 n(region
+, **connect_args
 )%0A    fo
@@ -2672,16 +2672,32 @@
 estCount
+, CPUUtilization
 %0A       
@@ -2732,16 +2732,25 @@
  AWS/ELB
+, AWS/EC2
 %0A       
@@ -2782,16 +2782,25 @@
 ,  # Sum
+, Maximum
 %0A       
@@ -2869,16 +2869,34 @@
 'Unit'%5D,
+  # Count, Percent
 %0A       
@@ -3259,16 +3259,48 @@
 ('-n'))%0A
+    verbose = options.pop('-v')%0A
     lead
@@ -3331,16 +3331,25 @@
 , count,
+ verbose,
  **optio

add a verbosity flag to help debugging