#!/usr/bin/env python -B
# code: utf-8
# python2

# TODO create example config import 

import argparse, sys, os, ConfigParser

import quick_clone.export_db
import quick_clone.import_db

VERSION = "0.0.1"

#default values
cwd = os.getcwd()
options = {
    "user"            : "root"
    , "host"          : "127.0.0.1"
    , "port"          : 3306
    , "dir"           : cwd
    , "tables"        : None
    , "fk"            : True
}

parser = argparse.ArgumentParser(
    prog="quick_clone",
    usage="quick_clone [sub-command] [options]",
    description="Quickly clone a MySQL database via INTO OUTFILE & LOAD DATA INFILE vs mysqldump.",
    epilog="Delorum")

parser.add_argument(
    "-v",
    "--version",
    help="Returns version",
    action="version",
    version="quick_clone " + VERSION)

# SUBCOMMANDS
sub_commands = parser.add_subparsers(
    title="Sub Commands",
    metavar="")

parser_export = sub_commands.add_parser(
    "export",
    usage="quick_clone export [options]",
    help="Export database using command line to pass arguments.",
    epilog="")

parser_export_config = sub_commands.add_parser(
    "export_config",
    usage="quick_clone export_config -c \'path/to/config.cfg\'",
    help="Export database using a config file to pass arguments.",
    epilog="")

parser_export_config_example = sub_commands.add_parser(
    "export_config_eg",
    usage="quick_clone export_config_eg",
    help="Create example export config file in the current directory",
    epilog="")

parser_import = sub_commands.add_parser(
    "import",
    usage="quick_clone import [options]",
    help="Import file using command line to pass arguments.",
    epilog="")

parser_import_config = sub_commands.add_parser(
    "import_config",
    usage="quick_clone export_config -c \'path/to/config.cfg\'",
    help="Import database using config file to pass arguments.",
    epilog="")

parser_import_config_example = sub_commands.add_parser(
    "import_config_eg",
    usage="quick_clone import_config_example",
    help="Create example import config file in the current directory",
    epilog="")

# EXPORT OPTIONS
parser_export.add_argument(
    "-u",
    "--user",
    dest="user",
    help="Database username. Defaults to 'root'.",
    metavar="USERNAME",
    default=options["user"])

parser_export.add_argument(
    "-p",
    "--pass",
    dest="password",
    help="* Database password.",
    metavar="PASSWORD",
    required=True)

parser_export.add_argument(
    "-H",
    "--host",
    dest="host",
    help="Database Host. Defaults to '127.0.0.1'",
    metavar="HOST",
    default=options["host"])

parser_export.add_argument(
    "-P",
    "--port",
    dest="port",
    help="Database Host. Defaults to 3306",
    metavar="PORT",
    type=int,
    default=options["port"])

parser_export.add_argument(
    "-d",
    "--database",
    dest="database",
    help="* Database Name",
    metavar="DATABASE",
    required=True)

parser_export.add_argument(
    "-D",
    "--dir",
    dest="dir",
    help="Preferred directory for export to be placed in. File name will be database name. Defaults to current directory.",
    metavar="DIR",
    default=options["dir"])

parser_export.add_argument(
    "-t",
    "--tables",
    dest="tables",
    help="Limit tables exported. Comma separated list(e.g. table_1,table_2,table_3). Defaults to all tables.",
    metavar="TABLES")

# EXPORT CONFIG OPTIONS
parser_export_config.add_argument(
    "-c",
    "--config_file",
    dest="config",
    help="Path to config file containing options. Defaults to 'quick_clone_export.cfg'",
    metavar="PATH",
    default="quick_clone_export.cfg")

# IMPORT OPTIONS
parser_import.add_argument(
    "-u",
    "--user",
    dest="user",
    help="Database Username. Defaults to 'root'.",
    metavar="USERNAME",
    default=options["user"])

parser_import.add_argument(
    "-p",
    "--pass",
    dest="password",
    help="* Database Password.",
    metavar="PASSWORD",
    required=True)

parser_import.add_argument(
    "-H",
    "--host",
    dest="host",
    help="Database Host. Defaults to '127.0.0.1'",
    metavar="HOST",
    default=options["host"])

parser_import.add_argument(
    "-P",
    "--port",
    dest="port",
    help="Database Host. Defaults to 3306",
    metavar="PORT",
    type=int,
    default=options["port"])

parser_import.add_argument(
    "-d",
    "--database",
    dest="database",
    help="* Database Name",
    metavar="DATABASE",
    required=True)

# we need file name since database names are most likely different
parser_import.add_argument(
    "-f",
    "--file",
    dest="file",
    help="* Relative or absolute path to file created by export.",
    metavar="PATH",
    required=True)

parser_import.add_argument(
    "-fk",
    "--fk",
    dest="fk",
    help="Whether foreign key constraints should be recreated. Defaults to True. (Boolean)",
    metavar="FILE",
    default=options["fk"])

# IMPORT CONFIG OPTIONS
parser_import_config.add_argument(
    "-c",
    "--config_file",
    dest="config",
    help="Relative or absolute path of file to import. Defaults to 'quick_clone_export.cfg'",
    metavar="PATH",
    default="quick_clone_import.cfg")

def main():

    # parse arguments from command line
    args = parser.parse_args()

    # prepare options dict from command line
    if sys.argv[1] == "export" or sys.argv[1] == "import":
        print "Preparing arguments from command line..."
        #convert to dictionary
        args = vars(args)
        # update options with those from command line
        for arg, value in args.iteritems():
            options[arg] = value

    # prepare options dict from config file
    elif sys.argv[1] == "export_config" or sys.argv[1] == "import_config":
        print "Preparing arguments from config file..."
        config_file = ConfigParser.RawConfigParser()
        # read config file
        config_file.read(args.config)
        # get config options from config file
        configs = config_file.items('Quick Clone')
        # update options with those from config file
        for config, value in configs:
            # get port as integer
            if config == 'port':
                options[config] = int(value)
            # get fk as boolean
            elif config == 'fk':
                options[config] = config_file.getboolean('Quick Clone', config)
            else:
                options[config] = value

    # send options to export or import script
    if sys.argv[1] == "export" or sys.argv[1] == "export_config":
        # remove options that only apply to import
        del options["fk"]
        quick_clone.export_db.execute(**options)
    elif sys.argv[1] == "import" or sys.argv[1] == "import_config":
        # remove options that only apply to export
        del options["dir"]
        del options["tables"]
        quick_clone.import_db.execute(**options)

    elif sys.argv[1] == "export_config_eg":
        config = ConfigParser.RawConfigParser()

        config.add_section('Quick Clone')
        config.set('Quick Clone', 'user     ', 'root')
        config.set('Quick Clone', 'password ', 'root')
        config.set('Quick Clone', 'host     ', '127.0.0.1')
        config.set('Quick Clone', 'port     ', '3306')
        config.set('Quick Clone', 'database ', 'database_name')
        config.set('Quick Clone', '# dir    ', '/tmp')
        config.set('Quick Clone', '# tables ', 'table_1,table_2,table_3')

        with open('quick_clone_export.cfg', 'wb') as configfile:
            config.write(configfile)
        print "Config file created at: " + os.getcwd() + "/quick_clone_export.cfg"

    elif sys.argv[1] == "import_config_eg":
        config = ConfigParser.RawConfigParser()

        config.add_section('Quick Clone')
        config.set('Quick Clone', 'user     ', 'root')
        config.set('Quick Clone', 'password ', 'root')
        config.set('Quick Clone', 'host     ', '127.0.0.1')
        config.set('Quick Clone', 'port     ', '3306')
        config.set('Quick Clone', 'database ', 'database_name')
        config.set('Quick Clone', 'file     ', 'path/to/export/file.tar.gz')
        config.set('Quick Clone', '# fk       ', 'False')

        with open('quick_clone_import.cfg', 'wb') as configfile:
            config.write(configfile)
        print "Config file created at: " + os.getcwd() + "/quick_clone_import.cfg"

    else:
        pass

if __name__ == '__main__':
    main()