#!/usr/bin/env python3
# Copyright © 2020 Arm Ltd. All rights reserved.
# Copyright 2020 NXP
# SPDX-License-Identifier: MIT
"""Python bindings for Arm NN

PyArmNN is a python extension for Arm NN SDK providing an interface similar to Arm NN C++ API.
"""
__version__ = None
__arm_ml_version__ = None

import logging
import os
import sys
import subprocess
from functools import lru_cache
from pathlib import Path
from itertools import chain

from setuptools import setup
from distutils.core import Extension
from setuptools.command.build_py import build_py
from setuptools.command.build_ext import build_ext

logger = logging.Logger(__name__)

DOCLINES = __doc__.split("\n")
LIB_ENV_NAME = "ARMNN_LIB"
INCLUDE_ENV_NAME = "ARMNN_INCLUDE"


def check_armnn_version(*args):
    pass

__current_dir = os.path.dirname(os.path.realpath(__file__))

exec(open(os.path.join(__current_dir, 'src', 'pyarmnn', '_version.py'), encoding="utf-8").read())


class ExtensionPriorityBuilder(build_py):
    """Runs extension builder before other stages. Otherwise generated files are not included to the distribution.
    """

    def run(self):
        self.run_command('build_ext')
        return super().run()


class ArmnnVersionCheckerExtBuilder(build_ext):
    """Builds an extension (i.e. wrapper). Additionally checks for version.
    """

    def __init__(self, dist):
        super().__init__(dist)
        self.failed_ext = []

    def build_extension(self, ext):
        try:
            super().build_extension(ext)
        except Exception as err:
            self.failed_ext.append(ext)
            logger.warning('Failed to build extension %s. \n %s', ext.name, str(err))

        if ext.name == 'pyarmnn._generated._pyarmnn_version':
            sys.path.append(os.path.abspath(os.path.join(self.build_lib, str(Path(ext._file_name).parent))))
            from _pyarmnn_version import GetVersion
            check_armnn_version(GetVersion(), __arm_ml_version__)

    def copy_extensions_to_source(self):

        for ext in self.failed_ext:
            self.extensions.remove(ext)
        super().copy_extensions_to_source()


def linux_gcc_name():
    """Returns the name of the `gcc` compiler. Might happen that we are cross-compiling and the
    compiler has a longer name.
    
    Args:
        None

    Returns:
        str: Name of the `gcc` compiler or None
    """
    cc_env = os.getenv('CC')
    if cc_env is not None:
        if subprocess.Popen([cc_env, "--version"], stdout=subprocess.DEVNULL):
            return cc_env
    return "gcc" if subprocess.Popen(["gcc", "--version"], stdout=subprocess.DEVNULL) else None


def linux_gcc_lib_search(gcc_compiler_name: str = linux_gcc_name()):
    """Calls the `gcc` to get linker default system paths.
    
    Args:
        gcc_compiler_name(str): Name of the GCC compiler

    Returns:
        list: A list of paths.

    Raises:
        RuntimeError: If unable to find GCC.
    """
    if gcc_compiler_name is None:
        raise RuntimeError("Unable to find gcc compiler")
    cmd1 = subprocess.Popen([gcc_compiler_name, "--print-search-dirs"], stdout=subprocess.PIPE)
    cmd2 = subprocess.Popen(["grep", "libraries"], stdin=cmd1.stdout,
                         stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
    cmd1.stdout.close()
    out, _ = cmd2.communicate()
    out = out.decode("utf-8").split('=')
    return tuple(out[1].split(':')) if len(out) > 0 else None


def find_includes(armnn_include_env: str = INCLUDE_ENV_NAME):
    """Searches for ArmNN includes.

    Args:
        armnn_include_env(str): Environmental variable to use as path.

    Returns:
        list: A list of paths to include.
    """
    armnn_include_path = os.getenv(armnn_include_env)
    if armnn_include_path is not None and os.path.exists(armnn_include_path):
        armnn_include_path = [armnn_include_path]
    else:
        armnn_include_path = ['/usr/local/include', '/usr/include']
    return armnn_include_path


@lru_cache(maxsize=1)
def find_armnn(lib_name: str,
               optional: bool = False,
               armnn_libs_env: str = LIB_ENV_NAME,
               default_lib_search: tuple = linux_gcc_lib_search()):
    """Searches for ArmNN installation on the local machine.

    Args:
        lib_name(str): Lib name to find.
        optional(bool): Do not fail if optional. Default is False - fail if library was not found.
        armnn_libs_env(str): Custom environment variable pointing to ArmNN libraries location, default is 'ARMNN_LIBS'
        default_lib_search(tuple): list of paths to search for ArmNN if not found within path provided by 'ARMNN_LIBS'
                            env variable
    Returns:
        tuple: Contains name of the armnn libs, paths to the libs.

    Raises:
        RuntimeError: If armnn libs are not found.
    """
    armnn_lib_path = os.getenv(armnn_libs_env)
    lib_search = [armnn_lib_path] if armnn_lib_path is not None else default_lib_search
    armnn_libs = dict(map(lambda path: (':{}'.format(path.name), path),
                          chain.from_iterable(map(lambda lib_path: Path(lib_path).glob(lib_name),
                                                  lib_search))))
    if not optional and len(armnn_libs) == 0:
        raise RuntimeError("""ArmNN library {} was not found in {}. Please install ArmNN to one of the standard
                           locations or set correct ARMNN_INCLUDE and ARMNN_LIB env variables.""".format(lib_name,
                                                                                                         lib_search))

    # gives back tuple of names of the libs, set of unique libs locations and includes.
    return list(armnn_libs.keys()), list(set(
        map(lambda path: str(path.absolute().parent), armnn_libs.values())))


class LazyArmnnFinderExtension(Extension):
    """Derived from `Extension` this class adds ArmNN libraries search on the user's machine.
    SWIG options and compilation flags are updated with relevant ArmNN libraries files locations (-L) and headers (-I).

    Search for ArmNN is executed only when attributes include_dirs, library_dirs, runtime_library_dirs, libraries or
    swig_opts are queried.

    """

    def __init__(self, name, sources, armnn_libs, include_dirs=None, define_macros=None, undef_macros=None,
                 library_dirs=None,
                 libraries=None, runtime_library_dirs=None, extra_objects=None, extra_compile_args=None,
                 extra_link_args=None, export_symbols=None, language=None, optional=None, **kw):
        self._include_dirs = None
        self._library_dirs = None
        self._runtime_library_dirs = None
        self._armnn_libs = armnn_libs
        # self.__swig_opts = None
        super().__init__(name, sources, include_dirs, define_macros, undef_macros, library_dirs, libraries,
                         runtime_library_dirs, extra_objects, extra_compile_args, extra_link_args, export_symbols,
                         language, optional, **kw)

    @property
    def include_dirs(self):
        return self._include_dirs + find_includes()

    @include_dirs.setter
    def include_dirs(self, include_dirs):
        self._include_dirs = include_dirs

    @property
    def library_dirs(self):
        library_dirs = self._library_dirs
        for lib in self._armnn_libs:
            _, lib_path = find_armnn(lib)
            library_dirs = library_dirs + lib_path

        return library_dirs

    @library_dirs.setter
    def library_dirs(self, library_dirs):
        self._library_dirs = library_dirs

    @property
    def runtime_library_dirs(self):
        library_dirs = self._runtime_library_dirs
        for lib in self._armnn_libs:
            _, lib_path = find_armnn(lib)
            library_dirs = library_dirs + lib_path

        return library_dirs

    @runtime_library_dirs.setter
    def runtime_library_dirs(self, runtime_library_dirs):
        self._runtime_library_dirs = runtime_library_dirs

    @property
    def libraries(self):
        libraries = self._libraries
        for lib in self._armnn_libs:
            lib_names, _ = find_armnn(lib)
            libraries = libraries + lib_names

        return libraries

    @libraries.setter
    def libraries(self, libraries):
        self._libraries = libraries

    def __eq__(self, other):
        return self.__class__ == other.__class__ and self.name == other.name

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return self.name.__hash__()


if __name__ == '__main__':
    # mandatory extensions
    pyarmnn_module = LazyArmnnFinderExtension('pyarmnn._generated._pyarmnn',
                                              sources=['src/pyarmnn/_generated/armnn_wrap.cpp'],
                                              extra_compile_args=['-std=c++14'],
                                              language='c++',
                                              armnn_libs=['libarmnn.so']
                                              )
    pyarmnn_v_module = LazyArmnnFinderExtension('pyarmnn._generated._pyarmnn_version',
                                                sources=['src/pyarmnn/_generated/armnn_version_wrap.cpp'],
                                                extra_compile_args=['-std=c++14'],
                                                language='c++',
                                                armnn_libs=['libarmnn.so']
                                                )
    extensions_to_build = [pyarmnn_v_module, pyarmnn_module]


    # optional extensions
    def add_parsers_ext(name: str, ext_list: list):
        pyarmnn_optional_module = LazyArmnnFinderExtension('pyarmnn._generated._pyarmnn_{}'.format(name.lower()),
                                                           sources=['src/pyarmnn/_generated/armnn_{}_wrap.cpp'.format(
                                                               name.lower())],
                                                           extra_compile_args=['-std=c++14'],
                                                           language='c++',
                                                           armnn_libs=['libarmnn.so', 'libarmnn{}.so'.format(name)]
                                                           )
        ext_list.append(pyarmnn_optional_module)


    add_parsers_ext('CaffeParser', extensions_to_build)
    add_parsers_ext('OnnxParser', extensions_to_build)
    add_parsers_ext('TfParser', extensions_to_build)
    add_parsers_ext('TfLiteParser', extensions_to_build)

    setup(
        name='pyarmnn',
        version=__version__,
        author='Arm Ltd, NXP Semiconductors',
        author_email='support@linaro.org',
        description=DOCLINES[0],
        long_description="\n".join(DOCLINES[2:]),
        url='https://mlplatform.org/',
        license='MIT',
        keywords='armnn neural network machine learning',
        classifiers=[
            'Development Status :: 3 - Alpha',
            'Intended Audience :: Developers',
            'Intended Audience :: Education',
            'Intended Audience :: Science/Research',
            'License :: OSI Approved :: MIT License',
            'Programming Language :: Python :: 3',
            'Programming Language :: Python :: 3 :: Only',
            'Programming Language :: Python :: 3.6',
            'Programming Language :: Python :: 3.7',
            'Programming Language :: Python :: 3.8',
            'Topic :: Scientific/Engineering',
            'Topic :: Scientific/Engineering :: Artificial Intelligence',
            'Topic :: Software Development',
            'Topic :: Software Development :: Libraries',
            'Topic :: Software Development :: Libraries :: Python Modules',
        ],
        package_dir={'': 'src'},
        packages=[
            'pyarmnn',
            'pyarmnn._generated',
            'pyarmnn._quantization',
            'pyarmnn._tensor',
            'pyarmnn._utilities'
        ],
        data_files=[('', ['LICENSE'])],
        python_requires='>=3.5',
        install_requires=['numpy'],
        cmdclass={
            'build_py': ExtensionPriorityBuilder, 
            'build_ext': ArmnnVersionCheckerExtBuilder
        },
        ext_modules=extensions_to_build
    )
