#!python

__VERSION__ = (1, 0, 2)
__VERSION_STRING__ = '.'.join(str(v) for v in __VERSION__)


import sys
import argparse
import traceback

import pydbvolve


if __name__ == '__main__':
    def init_args():
        """Initialize argument parser. Returns argparse.ArgumentParser instance."""
        
        description = "Apply migrations to a database. "
        description += "Be careful!! This script will happily run *any* migration code you are able to with "
        description += "your database user's permissions! Make sure that you have tested backup and recovery "
        description += "procedures in place before using this script. Migration scripts are matched by version. "
        description += "Only SQL (.sql) and Python (.py) migration scripts are supported."
        
        parser = argparse.ArgumentParser(description=description)
        parser.add_argument("--config",             dest="configFileName",    metavar="CONF_FILE",  required=True,  help="Config code file")
        parser.add_argument("--force",              dest="sequential",        action="store_false",                 help="Apply version directly (no sequential iteration through versions)", default=True)
        parser.add_argument("--verbose",            dest="verbose",           action="store_true",                  help="Verbose mode (Echo log to screen; Show tracebacks.)", default=False)
        parser.add_argument("--libversion",         dest="libversion",        action="store_true",                  help="Print the library version and exit", default=False)
        parser.add_argument("--version",            dest="version",           action="store_true",                  help="Print the main script version and exit", default=False)
        mgroup = parser.add_mutually_exclusive_group(required=True)
        mgroup.add_argument("--baseline",           dest="baselineVersion",   metavar="B_VERSION",                  help="Set baseline version in migration table")
        mgroup.add_argument("--baseline-current",   dest="baselineCurrent",   action="store_true",                  help="Set baseline version to the current version", default=False)
        mgroup.add_argument("--upgrade",            dest="upgradeVersion",    metavar="U_VERSION",                  help="Sequential upgrade to version")
        mgroup.add_argument("--upgrade-latest",     dest="upgradeLatest",     action="store_true",                  help="Sequential upgrade to latest version", default=False)
        mgroup.add_argument("--downgrade",          dest="downgradeVersion",  metavar="D_VERSION",                  help="Sequential downgrade to version")
        mgroup.add_argument("--downgrade-baseline", dest="downgradeBaseline", action="store_true",                  help="Sequential downgrade to version", default=False)
        mgroup.add_argument("--info",               dest="getInfo",           action="store_true",                  help="Get the current version information", default=False)
        mgroup.add_argument("--baseline-info",      dest="getBaselineInfo",   action="store_true",                  help="Get the baseline version information", default=False)
        mgroup.add_argument("--migration-log",      dest="migrationLog",      action="store_true",                  help="Output migration log from database.", default=False)
        mgroup.add_argument("--verify",             dest="verifyVersion",     metavar="V_VERSION",                  help="Verify the schema is at specified version")
        
        return parser
    # End init_args


    def main():
        """Main function for command-line execution."""
        parser = init_args()
        try:
            if '--libversion' in sys.argv:
                print("pydbovlve module version {}".format(pydbvolve.__VERSION_STRING__))
                return 0
            
            if '--version' in sys.argv:
                print("version {}".format(__VERSION_STRING__))
                return 0
                
            args = parser.parse_args()
        except:
            return -1
        
        if args.libversion:
            print("pydbovlve module version {}".format(pydbvolve.__VERSION_STRING__))
            return 0
        
        if args.version:
            print("version {}".format(__VERSION_STRING__))
            return 0
        
        if args.baselineVersion:
            action = 'baseline'
            version = args.baselineVersion
        elif args.baselineCurrent:
            action = 'baseline'
            version = pydbvolve.CURRENT_VERSION
        elif args.upgradeVersion:
            action = 'upgrade'
            version = args.upgradeVersion
        elif args.upgradeLatest:
            action = 'upgrade'
            version = pydbvolve.LATEST_VERSION
        elif args.downgradeVersion:
            action = 'downgrade'
            version = args.downgradeVersion
        elif args.downgradeBaseline:
            action = 'downgrade'
            version = pydbvolve.BASELINE_VERSION
        elif args.getInfo:
            action = 'info'
            version = pydbvolve.CURRENT_VERSION
        elif args.getBaselineInfo:
            action = 'info'
            version = pydbvolve.BASELINE_VERSION
        elif args.migrationLog:
            action = 'log'
            version = 'all'
        else: #args.verifyVersion:
            action = 'verify'
            version = args.verifyVersion
        
        sequential = args.sequential
        verbose = args.verbose
        
        rc = pydbvolve.run_migration(args.configFileName, action, version, sequential, verbose, chatty=True)
        
        return rc
    # End main
    
    # Execute!
    try:
        rc = main()
        if rc != 0:
            print("Exiting with {}".format(rc), file=sys.stderr)
        else:
            print("Done.")
        
        sys.exit(rc)
    except Exception as e:
        print("ERROR:: Unhandled excaption {}: {}".format(type(e).__name__, e), file=sys.stderr)
        traceback.print_exc(file=sys.stderr)
        sys.exit(254)


