"""
Wrapper for Storage Connector API when running outside a HANA environment, e.g. during installation.
"""

import sys, os
import ConfigParser

def main():
    configPath  = None
    clientLib   = None
    module      = None
    sid         = None
    datapath    = None
    logpath     = None
    tracelvl    = "WARNING"
    method      = "attach"
    partition   = None
    
    if len(sys.argv) <= 1 or "-h" in sys.argv or "--help" in sys.argv:
        print "Usage:"
        print "  python hdbmount.py --sid=<sid>|--configFiles=<path> --datapath=<path> --logpath=<path> --partition=<storage partition> [--detach] [--tracelevel=DEBUG|INFO|WARNING|ERROR|FATAL]"
        print
        print "    --sid              the SID of the installation (needed for determining the standard config file path; instead of --configFiles option)"
        print "    --configFiles      path to config files (instead of --sid option)"
        print "    --datapath         path to mntXXXXX directory of data volumes"
        print "    --logpath          path to mntXXXXX directory of log volumes"
        print "    --partition        storage partition number"
        print "    --detach           detach storage devices, optional"
        print "    --tracelevel       optional trace level, default = INFO"
        print
        print "  python hdbmount.py --sudoers --configFiles=<path>"
        print
        print "    --configFiles      path to config files"
        print
        print "  python hdbmount.py --listpartitions --configFiles=<path>"
        print
        print "    --configFiles      path to config files"
        exit(1)

    for p in sys.argv:
        if p.startswith("--sid="):
            sid = p[6:]
        if p.startswith("--configFiles="):
            configPath = p[14:]
        if p.startswith("--datapath="):
            datapath = p[11:]
        if p.startswith("--logpath="):
            logpath = p[10:]
        if p.startswith("--partition="):
            partition = p[12:]
        if p.startswith("--tracelevel="):
            tracelvl = p[13:]
        if p == "--detach":
            method = "detach"
        if p == "--sudoers":
            method = "sudoers"
        if p == "--listpartitions":
            method = "listpartitions"

    if method == "sudoers" and configPath == None:
        print "--configFiles must be specified when using --sudoers option"
        exit(1)
    
    if method == "listpartitions" and configPath == None:
        print "--configFiles must be specified when using --listpartitions option"
        exit(1)

    if configPath == None:
        configPath = "/usr/sap/%s/SYS/global/hdb/custom/config" % sid

    if method != "sudoers" and method != "listpartitions":
        if sid == None or datapath == None or logpath == None or partition == None:
            print "--sid, --partition, --datapath and --logpath must be specified"
            exit(1)


    # put path of hdbmount to PYTHONPATH
    sys.path.insert(0, os.path.abspath(os.path.dirname(sys.argv[0])))
    sys.path.insert(0, os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), "hdb_ha"))
    sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(sys.argv[0]))))

    config = ConfigParser.ConfigParser()
    config.read(os.path.join(configPath, "global.ini"))
    try:
        syspath = config.get("storage", "ha_provider_path")
        if ":" in syspath:
            sp = syspath.split(":")
            for s in sp:
                sys.path.insert(0, s)
        else:
            sys.path.insert(0, syspath)
    except:
        pass

    if method != "sudoers" and method != "listpartitions":
        print "PYTHONPATH=%s" % sys.path

    clientLib = config.get("storage", "ha_provider")
    if clientLib == "":
        print "no ha provider defined: missing global.ini/[storage]/ha_proider parameter"
        exit(1)

    try:
        if method != "sudoers" and method != "listpartitions":
            print "trying: __import__('%s')" % clientLib
        module = __import__(clientLib, globals(), locals())
    except Exception as e:
        if method != "sudoers" and method != "listpartitions":
            print "failed with: %s" % e

        try:
            if method != "sudoers" and method != "listpartitions":
                print "trying: __import__('%s')" % clientLib.split(".")[0]
            module = __import__(clientLib.split(".")[0], globals(), locals())
        except Exception as e:
            if method != "sudoers" and method != "listpartitions":
                print "failed with: %s" % e

            try:
                if method != "sudoers" and method != "listpartitions":
                    print "trying: __import__('%s')" % clientLib.split(".")[1]
                module = __import__(clientLib.split(".")[1], globals(), locals())
            except Exception as e:
                print "failed with: %s" % e
                print "please check loadability of your Storage Connector"
                exit(1)

    try:
        if method != "sudoers" and method != "listpartitions":
            print "trying: getattr(%s, '%s')" % (module, clientLib)
        clClass = getattr(module, clientLib)
    except Exception as e:
        if method != "sudoers" and method != "listpartitions":
            print "failed with: %s" % e
        try:
            if method != "sudoers" and method != "listpartitions":
                print "trying: getattr(getattr(%s, '%s'), '%s')" % (module, clientLib.split(".")[-1], clientLib.split(".")[-1])
            clClass = getattr(getattr(module, clientLib.split(".")[-1]), clientLib.split(".")[-1])
        except Exception as e:
            if method != "sudoers" and method != "listpartitions":
                print "failed with: %s" % e
            try:
                if method != "sudoers" and method != "listpartitions":
                    print "trying: getattr(%s, '%s')" % (module, clientLib.split(".")[-1])
                clClass = getattr(module, clientLib.split(".")[-1])
            except Exception as e:
                print "failed with: %s" % e
                print "please check loadability of your Storage Connector"
                exit(1)


    try:
        apiVersion = int(clClass.apiVersion)
    except:
        apiVersion = 1

    if method != "sudoers" and method != "listpartitions":
        print "apiVersion = %s" % apiVersion
        print "calling Storage Connector ..."

    if method == "sudoers":
        print clClass.sudoers().strip()
        exit(0)

    if apiVersion >= 2:
        cl = clClass(method, configPath, sid, datapath, logpath, tracelvl, partition)
    else:
        # skip mounting of too old scripts
        exit(0)

    if method != "sudoers" and method != "listpartitions":
        print "... done"

if __name__ == '__main__':
    main()
