#!/usr/bin/env python

# -*- encoding: utf-8 -*-
import argparse
import logging
import os
import pickle
import sys

import eventlet
from keystoneclient.v2_0 import client as ksclient

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from swsync import filler
from swsync import utils


def main():
    parser = argparse.ArgumentParser(prog='swift-filler',
                                     add_help=True)
    parser.add_argument('--delete',
                        action='store_true',
                        help='Suppress created accounts/users')
    parser.add_argument('--create',
                        action='store_true',
                        help='Create account/users/containers/data')
    parser.add_argument('-l',
                        action='store_true',
                        help='Load previous indexes and append newly'
                        ' created to it')
    parser.add_argument('-a',
                        help='Specify account amount')
    parser.add_argument('-u',
                        help='Specify user amount by account')
    parser.add_argument('-c',
                        help='Specify container amount by account')
    parser.add_argument('-f',
                        help='Specify file amount by account')
    parser.add_argument('-s',
                        help='Specify the MAX file size. Files '
                        'will be from 1024 Bytes to MAX Bytes')
    parser.add_argument('-d', '--log-level',
                        dest='log_level',
                        default='info',
                        help='Specify the log level')
    parser.add_argument('--config',
                        dest='config',
                        help='Optional configuration file path')
    args = parser.parse_args()

    utils.set_logging(args.log_level)

    if args.config and os.path.isfile(args.config):
        try:
            conf = utils.parse_ini(args.config)
        except Exception, exc:
            logging.info('Unable to parse provided conf file')
            logging.error(exc)
            sys.exit(1)
    else:
        try:
            conf = utils.parse_ini()
        except(utils.ConfigurationError):
            parser.print_help()
            sys.exit(1)

    utils.CONFIG = conf

    if not args.create and not args.delete:
        parser.print_help()
        sys.exit(1)
    if args.create and args.delete:
        parser.print_help()
        sys.exit(1)

    sw_c_concu = int(utils.get_config('concurrency',
                                      'filler_swift_client_concurrency'))
    ks_c_concu = int(utils.get_config('concurrency',
                                      'filler_keystone_client_concurrency'))
    pile = eventlet.GreenPile(sw_c_concu)
    pool = eventlet.GreenPool(ks_c_concu)

    _config = utils.get_config('auth',
                               'keystone_origin_admin_credentials').split(':')
    tenant_name, username, password = _config
    client = ksclient.Client(
        auth_url=utils.get_config('auth', 'keystone_origin'),
        username=username,
        password=password,
        tenant_name=tenant_name)

    index_path = utils.get_config('filler', 'index_path')
    index_containers_path = utils.get_config('filler', 'index_containers_path')

    if args.l:
        index = filler.load_index()
        index_containers = filler.load_containers_index()
    else:
        index = {}
        index_containers = {}
    if args.create:
        if args.a is None or not args.a.isdigit():
            logging.info("Provide account amount by setting '-a' option")
            sys.exit(1)
        if args.u is None or not args.u.isdigit():
            logging.info("Provide user by account "
                         "amount by setting '-u' option")
            sys.exit(1)
        if args.s is None:
            fmax = 1024
        else:
            if args.s.isdigit():
                fmax = max(1024, int(args.s))
            else:
                fmax = 1024
        created = filler.create_swift_account(client, pile,
                                              int(args.a),
                                              int(args.u), index=index)
        if args.f is not None and args.c is not None:
            if args.f.isdigit() and args.c.isdigit():
                filler.fill_swift(pool, created, int(args.c),
                                  int(args.f), fmax,
                                  index_containers=index_containers)
            else:
                logging.info("'-c' and '-f' options must be integers")
                sys.exit(1)
        pickle.dump(index, open(index_path, 'w'))
        pickle.dump(index_containers, open(index_containers_path, 'w'))
    if args.delete:
        index = filler.load_index()
        for k, v in index.items():
            user_info_list = [user[1] for user in v]
            # Take the first user we find
            filler.delete_account_content(k, v[0])
            filler.delete_account(client, user_info_list, k)
            del index[k]
        if not os.path.exists(index_path):
            logging.info("No index_path to load.")
            sys.exit(1)
        pickle.dump(index, open(index_path, 'w'))

if __name__ == '__main__':
    main()
