# CONFIDENTIAL. (C) 2022 Cadence Design Systems, Inc. (Cadence)
# All rights reserved.
# ALL SOFTWARE BELOW IS PROPRIETARY AND CONFIDENTIAL TO CADENCE
# AND IS SUBJECT TO THE FULL PROTECTION OF COPYRIGHT AND TRADE SECRET LAW.
# Copying or modifying this software is strictly prohibited and illegal.
# Using this software without a valid license from Cadence is strictly
# prohibited and illegal.  De-obfuscating, de-minimizing, or any other
# attempt to reverse engineer or discover the workings of this software,
# is strictly prohibited. Even if software is exposed or visible, it is
# still proprietary and confidential and the above prohibitions apply.
# This software is NOT "Sample Code". For purposes of customization or
# interoperation with other software you must use Sample Code
# specifically labeled as such.
# Please contact Cadence at eyesopen.com/legal if you have any questions
# about this warning.

import os
import sys
import platform
from .openeye_platform import openeye_python_version, openeye_platform, openeye_python_compilers, openeye_python_version

def SearchForCompatibleLibDirectory(compatible_compilers, archlist):
    base = os.path.abspath(os.path.dirname(__file__))
    pyver = openeye_python_version()

    tried = []
    for comp in compatible_compilers:
        for arch in archlist:
            if arch.endswith("x86"):
                if platform.architecture()[0] == "64bit":
                    raise ImportError("On x86 machine trying to use a 64-bit python")

            archname = '-'.join([arch, comp])

            tried.append(archname)
            dlls = os.path.join(base, archname)
            if os.path.exists(dlls):
                return tried, dlls

    return tried, None

def FindOpenEyeDLLSDirectory():
    archlist = '-'.join(openeye_platform())
    if "OE_PIP_ARCH" in os.environ:
        archlist = os.environ["OE_PIP_ARCH"].split(":")

    compatible_compilers = openeye_python_compilers()
    tried, dlls = SearchForCompatibleLibDirectory(compatible_compilers, archlist)
    if dlls is not None:
        return dlls

    base = os.path.abspath(os.path.dirname(__file__))

    # allow osx-es to use each other as a last resort
    if sys.platform == "darwin":
        pyver = openeye_python_version()
        for fname in os.listdir(base):
            dlls = os.path.join(base, fname)
            if (pyver in fname and
                "osx" in fname and
                os.path.isdir(dlls)):
                return dlls

    # allow linuxes to use each other as a last resort
    if sys.platform.startswith("linux"):
        pyver = openeye_python_version()
        for fname in os.listdir(base):
            dlls = os.path.join(base, fname)
            if (pyver in fname and
                "g++" in fname and
                "osx" not in fname and
                os.path.isdir(dlls)):
                return dlls

    installed = []
    for fname in os.listdir(base):
        if os.path.isdir(os.path.join(base, fname)):
            installed.append(fname)

    msg = """Unable to find OpenEye python toolkit installation for this architecture.
    The architecture for this python interpreter is: %s
    The directory searched for architecture specific libraries: %s
    Installations found in that directory:
    \t%s
    Please make sure the installed tar-ball exactly matches %s
    """
    arches = repr(tried)
    raise ImportError(msg % (arches, base, "\n\t".join(installed), arches))

if not sys.platform.startswith("win"):
    OPENEYE_DLLS = FindOpenEyeDLLSDirectory()

def OEGetModule(name):
    if sys.platform == "darwin" and "DYLD_LIBRARY_PATH" in os.environ:
        # check for clash
        soname = "%s.so" % name
        for dname in os.environ["DYLD_LIBRARY_PATH"].split(":"):
            if (dname and
                os.path.exists(os.path.join(dname, soname)) and
                not os.path.samefile(dname, OPENEYE_DLLS)):
                raise ImportError("Conflict found loading %r. Please remove %r from DYLD_LIBRARY_PATH." %
                                  (soname, soname))

    import importlib
    # find the module
    spec = importlib.machinery.PathFinder().find_spec(name, [OPENEYE_DLLS])

    # actually load the module
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)

    return mod

if sys.platform.startswith("win"):
    def OEGetModule(name):
        raise ImportError("OEGetModule should never be called on Windows")

