#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import glob

from distutils.command.build_ext import build_ext
from distutils.core import Extension
from distutils.errors import CCompilerError
from distutils.errors import DistutilsExecError
from distutils.errors import DistutilsPlatformError

# import numpy and cython
from Cython.Build import cythonize
import numpy

# the path for rice module and rpl
RICE_PATH = os.path.join("roc", "rpl", "rice")

# path to packet_structure for PacketParser
RPL_PACKET_STRUCTURE_PATH = os.path.join("roc", "rpl", "packet_structure")

# Path to packet_parser
RPL_PACKET_PARSER_PATH = os.path.join("roc", "rpl", "packet_parser", "parser")

# C Extensions
with_extensions = os.getenv("RPL_EXTENSIONS", None)

if with_extensions == "1" or with_extensions is None:
    with_extensions = True

if with_extensions == "0" or hasattr(sys, "pypy_version_info"):
    with_extensions = False

extensions = []
if with_extensions:
    extensions = list()
    extensions += cythonize(
        Extension(
            "roc.rpl.packet_structure.header",
            [
                "roc/rpl/packet_structure/header.pyx",
                "roc/rpl/packet_structure/type_conversion.c",
            ],
            include_dirs=[numpy.get_include(), RPL_PACKET_STRUCTURE_PATH],
        ),
        language_level="3",
    )
    extensions += cythonize(
        Extension(
            "roc.rpl.packet_structure.parameter",
            [
                "roc/rpl/packet_structure/parameter.pyx",
                "roc/rpl/packet_structure/type_conversion.c",
            ],
            include_dirs=[numpy.get_include(), RPL_PACKET_STRUCTURE_PATH],
        ),
        language_level="3",
    )
    extensions += cythonize(
        Extension(
            "roc.rpl.packet_structure.data",
            [
                "roc/rpl/packet_structure/data.pyx",
                "roc/rpl/packet_structure/type_conversion.c",
            ],
            include_dirs=[numpy.get_include(), RPL_PACKET_STRUCTURE_PATH],
        ),
        language_level="3",
    )
    extensions += cythonize(
        Extension(
            "roc.rpl.packet_parser.parser.identify_packets",
            sources=[
                "roc/rpl/packet_parser/parser/identify_packets.pyx",
                "roc/rpl/packet_structure/type_conversion.c",
            ],
            include_dirs=[
                numpy.get_include(),
                RPL_PACKET_PARSER_PATH,
                RPL_PACKET_STRUCTURE_PATH,
            ],
        ),
        language_level="3",
    )
    extensions += cythonize(
        Extension(
            "roc.rpl.packet_parser.parser.parse_packets",
            sources=[
                "roc/rpl/packet_parser/parser/parse_packets.pyx",
                "roc/rpl/packet_structure/type_conversion.c",
            ],
            include_dirs=[
                numpy.get_include(),
                RPL_PACKET_PARSER_PATH,
                RPL_PACKET_STRUCTURE_PATH,
            ],
        ),
        language_level="3",
    )

    # now add an extension for compiling the rice compression library
    extensions += cythonize(
        Extension(
            "roc.rpl.rice.rice",  # this will be the name of the module
            sources=[os.path.join(RICE_PATH, "rice.pyx")]
            + [
                fn
                for fn in glob.glob(os.path.join(RICE_PATH, "*.cpp"))
                if not os.path.basename(fn) == "rice.cpp"
            ],
            include_dirs=[numpy.get_include(), RICE_PATH, RPL_PACKET_STRUCTURE_PATH],
            language="c++",
            define_macros=[("GAUSS", "1")],
        ),
        language_level="3",
    )


class BuildFailed(Exception):
    pass


class ExtBuilder(build_ext):
    # This class allows C extension building to fail.

    def run(self):
        try:
            build_ext.run(self)
        except (DistutilsPlatformError, FileNotFoundError):
            print("************************************************************")
            print("Cannot compile RPL Cython module!")
            print("************************************************************")

    def build_extension(self, ext):
        try:
            build_ext.build_extension(self, ext)
        except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError):
            print("************************************************************")
            print("Cannot compile Cython module!")
            print("************************************************************")


def build(setup_kwargs):
    """
    This function is mandatory in order to build the extensions.
    """
    setup_kwargs.update(
        {"ext_modules": extensions, "cmdclass": {"build_ext": ExtBuilder}}
    )
