#!/usr/bin/python

import getopt, sys, os, string
from optparse import OptionParser,OptionGroup,make_option

prefix = "/usr/local"

if not (prefix + "/share/glusterfs") in sys.path:
    sys.path.append(prefix + "/share/glusterfs")

from CreateVolfile import *
from CreateBooster import *

def check_duplicate_entry(args):
    """Check duplicate entries in incoming arguments"""
    _tmp = []
    for server in args:
        if server not in _tmp:
            _tmp.append (server)
        else:
            print "Duplicate arguments detected (%s)" % server
            raise ValueError

    return

def args2dict(args):

    keyvalue = {}
    for arg in args:
        if int(arg.find(':')) == -1:
            continue
        first = arg.split(':')[0]
        keyvalue[first] = []

    for arg in args:
        if int(arg.find(':')) == -1:
            continue
        first = arg.split(':')[0]
        if arg.split(':')[1] not in keyvalue[first]:
            if arg.split(':')[1][0] != '/':
                print "Absolute export path required for %s" % arg
                raise ValueError
            keyvalue[first].append (arg.split(':')[1])

    return keyvalue

def args2array(args):

    array = []

    for arg in args:
        if int(arg.find(':')) == -1:
            continue
        array.append(arg)

    return array

def generate_volume_files ():

    num_stripe = 4
    num_replica = 2

    usage_str = "%prog: -n <VOLUMENAME> -t <TRANSPORT> -p <NUMBER> -a <AUTH> -r <TYPE>"
    version_str = "%prog 3.0"
    desc_str = "A tool to generate volume files for GlusterFS."

    parse = OptionParser(usage=usage_str, version=version_str, description=desc_str)

    # Basic option list
    group = OptionGroup(parse, "Basic Options")
    group.add_option("-n", "--name", dest="volume_name",
                help="<volume-name>")
    group.add_option("-t", "--transport", dest="transport_type",
                default="tcp", help="tcp,ib-verbs default: tcp")
    group.add_option("-p", "--port", type="int",
                dest="port", default=6996,
                help="<port> number")
    group.add_option("-a", "--auth", dest="auth_param", default="*",
                help="comma seperated ip range")
    group.add_option("-r", "--raid", type="int", dest="raid_type",
                help="0|1")
    group.add_option("--nfs", action="store_true", dest="need_nfs",
                default=False, help="booster nfs reexport")
    group.add_option("--cifs", action="store_true", dest="need_cifs",
                default=False, help="booster cifs reexport")
    parse.add_option_group(group)

    # CIFS option list
    group = OptionGroup(parse, "CIFS Options")
    group.add_option("--username", dest="cifs_username",
                     default="gluster", help="<cifs_username>")
    group.add_option("--guest", action="store_true",
                     dest="enable_guest", default=False,
                     help="enable guest access")
    parse.add_option_group(group)
    # NFS option list

    # Advanced option list
    group = OptionGroup(parse, "Advanced Options")
    group.add_option("--ibdev", type="int", dest="ib_dev",
                     default=1, help="Infiniband device number <N>")
    group.add_option("-c", "--conf-dir", dest="conf_dir",
                     help="output directory for volume files")
    group.add_option("--volume-size-server", dest="size_server",
                     help="volume size for each server")
    group.add_option("--volume-size-client", dest="size_client",
                     help="volume size for each client")

    parse.add_option_group(group)

    group = OptionGroup(parse, "Extra Options")
    group.add_option("--unused", action="store_true",
                     dest="unused", default=False,
                     help="enable unused options")
    group.add_option("--debug", action="store_true",
                     dest="debug", default=False,
                     help="add all debug modules to volumes")

    parse.add_option_group(group)

    (options, args) = parse.parse_args()

    if options.volume_name is None:
        print "Error: volume name is mandatory, please provide volume name"
        raise ValueError

    if options.transport_type:
        transports = options.transport_type.split(',')
        for transport in transports:
            if (transport != "tcp" and transport != "ib-verbs"):
                print "Error: --transport: option " + transport + \
                    " is not valid transport type"
                raise ValueError

    if options.raid_type:
        if (options.raid_type != 1 and options.raid_type != 0):
            print "Error: --raid: option " + str(options.raid_type) + " is not valid raid type"
            raise ValueError


    check_duplicate_entry(args)

    server_dict = {}

    server_dict = args2dict(args)

    server_array = args2array(args)

    if len (server_dict.keys()) == 0:
        print "Error: no servers provided, please provide atleast one server"
        raise ValueError

    if options.raid_type == 1:
        if (len(server_array) % num_replica) != 0:
            print "raid type (%d) and number of volumes (%d) invalid" % (options.raid_type,
                                                                         len(server_array))
            raise ValueError

    if options.raid_type == 0:
        if (len(server_array) % num_stripe) != 0:
            print "raid type (%d) and number of volumes (%d) invalid" % (options.raid_type,
                                                                         len(server_array))
            raise ValueError

    for server in server_dict.keys():
        create_exp = CreateVolfile (server_dict, server,
                                    None, transports,
                                    options, None)
        try:
            create_exp.create_export_volfile ()
        except IOError, (errno, strerror):
            print "Got %s creating server volfiles for %s" % (strerror, server)

    for transport in transports:
        create_mnt = CreateVolfile (server_dict, None,
                                    transport, transports,
                                    options, server_array)
        try:
            create_mnt.create_mount_volfile ()
        except IOError, (errno, strerror):
            print "Got %s creating client volfiles for transport '%s'" % (strerror, transport)


    create_booster = CreateBooster (options, transports)
    try:
        create_booster.configure_booster ()
    except IOError, (errno, strerror):
        print "Got %s creating booster configuration" % (strerror)

def main ():

    try:
        generate_volume_files()
    except ValueError:
        sys.exit(1)


main()
