#!/usr/bin/env python

import fileinput
import sys
import os
from docopt import docopt
import logging
import urllib3
import json

from tools import JsonPort, S3Port, ElasticPort, MongoPort, HbasePort, KafkaPort

from settings import (ES_SETTINGS, S3_SETTINGS,
                      MONGO_SETTINGS, HBASE_SETTINGS, KAFKA_SETTINGS)

# Local Overrides
# ~~~~~~~~~~~~~~~
from ConfigParser import SafeConfigParser

parser = SafeConfigParser()
parser.read(os.path.expanduser('~/.tport'))

if parser.has_section('elasticsearch'):
    ES_SETTINGS['host'] = parser.get('elasticsearch', 'host')
    ES_SETTINGS['ssl'] = bool(parser.get('elasticsearch', 'ssl'))

if parser.has_section('kafka'):
    KAFKA_SETTINGS['broker'] = parser.get('kafka', 'broker')

if parser.has_section('s3'):
    S3_SETTINGS['access_key'] = parser.get('s3', 'access_key')
    S3_SETTINGS['secret_key'] = parser.get('s3', 'secret_key')

if parser.has_section('mongo'):
    MONGO_SETTINGS['host'] = parser.get('mongo', 'host')
    MONGO_SETTINGS['db'] = parser.get('mongo', 'db')

if parser.has_section('hbase'):
    HBASE_SETTINGS['host'] = parser.get('hbase', 'host')

# cfg_dict = [dict(parser.items(cfg)) for cfg in parser.sections()]


# disable annoying SSL certificate warnings
urllib3.disable_warnings()

# set up a logger
logging.basicConfig(level=logging.INFO)


def main():
    """ transporter: Transport JSON data to different outputs.

    Usage:
        tport inspect FILE ...
        tport es create --indexname=<indexname>
        tport es map --indexname=<indexname> --doctype=<doctype> --mapping=<mapping>
        tport es index --indexname=<indexname> --doctype=<doctype> [--chunksize=<chunksize>] [--mapping=<mapping>] FILE ...
        tport kafka topics [--broker=<broker>]
        tport kafka produce --topic=<topic> [--broker=<broker>] FILE ...
        tport kafka consume --topic=<topic> [--broker=<broker>]
        tport s3 list
        tport s3 upload <bucket> [--replace=<replace>] [--compress] FILE ...
        tport s3 download <bucket> FOLDER
        tport s3 destroy <bucket>
        tport mongo list [--host=<host>] [--db=<db>]
        tport mongo preview [--host=<host>] [--db=<db>] --collection=<collection>
        tport mongo export [--host=<host>] [--db=<db>] --collection=<collection> [FILE ...]
        tport mongo add [--host=<host>] [--db=<db>] --collection=<collection> FILE ...
        tport hbase scan [--host=<host>] --table=<table>

    Options:
        -h --help
        -i --indexname <indexname>
        -d --doctype <doctype>
        -m --mapping <mapping>
        -c --chunksize <chunksize>
        -r --replace <replace>
        -t --topic <topic>
        -b --broker <broker>
    """

    args = docopt(main.__doc__)

    f = args['FILE']

    # logging.info(args)

    cli_jsonit = JsonPort(fileinput.input(f)) if f else None

    if args['inspect']:
        cli_jsonit.inspect()

    if args['es']:
        # Connect to elastic search
        esi = ElasticPort(ES_SETTINGS['host'], ES_SETTINGS['ssl'])
        cli_iname = args['--indexname']
        cli_dtype = args['--doctype']
        if args['create']:
            esi.create(cli_iname)
        if args['map']:
            with open(args['--mapping']) as fm:
                cli_mapping = json.load(fm)
            esi.map(cli_iname, cli_dtype, cli_mapping)
        if args['index']:
            cli_chunksize = args['--chunksize'] or 500
            cli_chunksize = int(cli_chunksize)
            # Create index if not created
            esi.create(cli_iname)
            if args['--mapping']:
                with open(args['--mapping']) as fm:
                    cli_mapping = json.load(fm)
                esi.map(cli_iname, cli_dtype, cli_mapping)

            esi.index(cli_jsonit.parse(), cli_iname, cli_dtype, cli_chunksize)

    if args['kafka']:
        ka_broker = args['--broker'] or KAFKA_SETTINGS['broker']
        kai = KafkaPort(ka_broker)
        if args['topics']:
            kai.topics()
        if args['produce']:
            cli_topic = args['--topic']
            kai.produce(cli_topic, cli_jsonit.parse())
        if args['consume']:
            cli_topic = args['--topic']
            kai.consume(cli_topic)

    if args['s3']:
        s3u = S3Port(S3_SETTINGS['access_key'], S3_SETTINGS['secret_key'])
        if args['list']:
            s3u.list()
        if args['upload']:
            cli_replace = args['--replace']
            cli_bucket = args['<bucket>']
            cli_compress = True if args['--compress'] else False
#            logging.info('upload starting...')
            s3u.upload(cli_bucket, f, cli_compress, cli_replace)
#            logging.info('upload complete')
        if args['download']:
            cli_folder = args['FOLDER']
            cli_bucket = args['<bucket>']
            s3u.download(cli_bucket, cli_folder)
        if args['destroy']:
            print 'You are about to DESTROY the entire {0} bucket!!!\n'.format(
                                                            args['<bucket>'])
            response = raw_input('Are you sure? [Y/n] ')
            if response == 'Y':
                s3u.destroy(args['<bucket>'])
            else:
                print """
                                               (@<
                 Chickening out....           (< )
                                               ^^
                      """

    if args['mongo']:
        # Connect to mongo database
        mg_host = MONGO_SETTINGS['host'] or args['--host']
        mg_db = MONGO_SETTINGS['db'] or args['--db']
        mgi = MongoPort(mg_host, mg_db)
        if args['list']:
            mgi.list()
        if args['preview']:
            mg_collection = args['--collection']
            mgi.preview(mg_collection)
        if args['export']:
            mg_collection = args['--collection']
            mgi.export(mg_collection, f)   # generator object

    if args['hbase']:
        hb_host = HBASE_SETTINGS['host'] or args['--host']
        hbi = HbasePort(hb_host)
        if args['scan']:
            hbi_table = args['--table']
            hbi.scan(hbi_table)

if __name__ == '__main__':
    sys.exit(main())
