"""
setup.py - Python module to install ittapi package
"""
import os
import sys

from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
from subprocess import run  # pylint: disable=C0411 # nosec B404
from shutil import which


def get_environment_flag(name):
    """
    Get an environment variable and check its value.
    :param name: the environment variable name
    :return: None if the environment variable is not set. False if the environment variable is set and has one of the
             following values: `''`, `0`, `n`, `no` or `false`. Otherwise, return True.
    """
    flag_value = os.environ.get(name, None)
    return (flag_value and flag_value.lower() not in ('0', 'n', 'no', 'false')) if flag_value is not None else None


# Check if custom location for ITT API source code is specified
ITT_DEFAULT_DIR = '../'
itt_dir = os.environ.get('ITTAPI_ITT_API_SOURCE_DIR', None)
itt_dir = itt_dir if itt_dir else ITT_DEFAULT_DIR

if not os.path.exists(itt_dir):
    raise FileNotFoundError('The specified directory with ITT API source code does not exist.')

if itt_dir == ITT_DEFAULT_DIR and not len(os.listdir(itt_dir)):
    raise ValueError(
        f'The specified directory with ITT API source code ({itt_dir}) is empty.\n'
        f'Please make sure you provide a valid path.'
    )

# Check if IPT support is requested
build_itt_with_ipt_support = get_environment_flag('ITTAPI_BUILD_WITH_ITT_API_IPT_SUPPORT')
build_itt_with_ipt_support = build_itt_with_ipt_support if build_itt_with_ipt_support is not None else True

itt_source = [os.path.join(itt_dir, 'src', 'ittnotify', 'ittnotify_static.c')]
itt_include_dirs = [os.path.join(itt_dir, 'include')]
itt_license_files = []
if itt_dir == ITT_DEFAULT_DIR:
    itt_license_files = [os.path.join(itt_dir, 'LICENSES', 'BSD-3-Clause.txt'),
                         os.path.join(itt_dir, 'LICENSES', 'GPL-2.0-only.txt')]

if build_itt_with_ipt_support:
    itt_compiler_flags = ['-DITT_API_IPT_SUPPORT']
    if sys.platform == 'win32':
        ITT_PTMARK_SOURCE = 'ittptmark64.asm'
    else:
        ITT_PTMARK_SOURCE = 'ittptmark64.S'
    itt_extra_objects = [os.path.join(itt_dir, 'src', 'ittnotify', ITT_PTMARK_SOURCE)]
else:
    itt_compiler_flags = []
    itt_extra_objects = []

ittapi_license_files = []
ittapi_native_sources = ['ittapi.native/extensions/python.cpp',
                        'ittapi.native/extensions/string.cpp',
                        'ittapi.native/collection_control.cpp',
                        'ittapi.native/domain.cpp',
                        'ittapi.native/event.cpp',
                        'ittapi.native/id.cpp',
                        'ittapi.native/string_handle.cpp',
                        'ittapi.native/task.cpp',
                        'ittapi.native/thread_naming.cpp',
                        'ittapi.native/pt_region.cpp',
                        'ittapi.native/ittapi.cpp']

ittapi_native_compiler_args = ['/std:c++20' if sys.platform == 'win32' else '-std=c++20']
if build_itt_with_ipt_support:
    ittapi_native_compiler_args.append('-DITTAPI_BUILD_WITH_ITT_API_IPT_SUPPORT=1')

ittapi_native = Extension('ittapi.native',
                         sources=itt_source + ittapi_native_sources,
                         include_dirs=itt_include_dirs,
                         extra_compile_args=itt_compiler_flags + ittapi_native_compiler_args,
                         extra_objects=itt_extra_objects)


class NativeBuildExtension(build_ext):  # pylint: disable=R0903
    """
    A class that implements the build extension to compile ittapi.native module.
    """
    def build_extension(self, ext) -> None:
        """
        Build native extension module
        :param ext: the extension to build
        """
        if ext.name == 'ittapi.native' and self.compiler.compiler_type == 'msvc':
            # Setup asm tool
            as_tool = 'ml64.exe'
            as_ext = '.asm'

            if hasattr(self.compiler, 'initialized') and hasattr(self.compiler, 'initialize'):
                if not self.compiler.initialized:
                    self.compiler.initialize()

            as_path = os.path.dirname(self.compiler.cc) if hasattr(self.compiler, 'cc') else ''

            # Validate assembler tool path (avoid untrusted execution)
            as_full_path = os.path.join(as_path, as_tool) if as_path else which(as_tool)
            if not as_full_path or not os.path.isfile(as_full_path):
                raise RuntimeError(f"Assembler tool not found: {as_tool}")

            # Extract asm files from extra objects
            # pylint: disable=W0106
            asm_files = [filename for filename in ext.extra_objects if filename.lower().endswith(as_ext)]
            [ext.extra_objects.remove(filename) for filename in asm_files]

            # Create temp directories
            [os.makedirs(os.path.join(self.build_temp, os.path.dirname(filename)), exist_ok=True)
             for filename in asm_files]

            # Generate target names
            src_dir = os.path.dirname(__file__)
            obj_asm_pairs = [(os.path.join(self.build_temp, os.path.splitext(filename)[0]) + '.obj',
                              os.path.join(src_dir, filename)) for filename in asm_files]
            # Compile
            [run([as_full_path, '/Fo', obj_file, '/c', asm_file], check=True) # nosec B603
             for obj_file, asm_file in obj_asm_pairs]

            [ext.extra_objects.append(obj_file) for obj_file, _ in obj_asm_pairs]

        build_ext.build_extension(self, ext)


setup(name='ittapi',
      version='1.2.1',
      description='ITT API bindings for Python',
      packages=['ittapi', 'ittapi/compat'],
      ext_modules=[ittapi_native],
      license_files=ittapi_license_files + itt_license_files,
      cmdclass={'build_ext': NativeBuildExtension} if build_itt_with_ipt_support else {},
      zip_safe=False)
