# Script for generating the mpact wheel.
# ```
# $ python setup.py bdist_wheel
# ```
# Environment variables you are probably interested in:
#
#   CMAKE_BUILD_TYPE:
#       specify the build type: DEBUG/RelWithDebInfo/Release
#
#   MPACT_CMAKE_ALREADY_BUILT:
#       the `MPACT_CMAKE_BUILD_DIR` directory has already been compiled,
#       and the CMake compilation process will not be executed again.
#       On CIs, it is often advantageous to re-use/control the CMake build directory.
#
# It is recommended to build with Ninja and ccache. To do so, set environment
# variables by prefixing to above invocations:
# ```
# CMAKE_GENERATOR=Ninja CMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_CXX_COMPILER_LAUNCHER=ccache
# ```
#
# Implementation notes:
# The contents of the wheel is just the contents of the `python_packages`
# directory that our CMake build produces. We go through quite a bit of effort
# on the CMake side to organize that directory already, so we avoid duplicating
# that here, and just package up its contents.

import os
import pathlib
import shutil
import subprocess
import sys

from datetime import date
from distutils.command.build import build as _build
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
from setuptools.command.build_py import build_py


def _check_env_flag(name: str, default=None) -> bool:
    return str(os.getenv(name, default)).upper() in ["ON", "1", "YES", "TRUE", "Y"]


PACKAGE_VERSION = "".join(str(date.today()).split("-"))
SRC_DIR = pathlib.Path(__file__).parent.absolute()
CMAKE_BUILD_TYPE = os.getenv("CMAKE_BUILD_TYPE", "Release")
MPACT_CMAKE_ALREADY_BUILT = _check_env_flag("MPACT_CMAKE_ALREADY_BUILT", False)
MPACT_CMAKE_BUILD_DIR = os.path.join(SRC_DIR, "build")


# Build phase discovery is unreliable. Just tell it what phases to run.
class CustomBuild(_build):
    def initialize_options(self):
        _build.initialize_options(self)
        # Make setuptools not steal the build directory name,
        # because the mlir c++ developers are quite
        # used to having build/ be for cmake
        self.build_base = "setup_build"

    def run(self):
        self.run_command("build_py")
        self.run_command("build_ext")
        self.run_command("build_scripts")


class CMakeBuild(build_py):
    def cmake_build(self, cmake_build_dir):
        llvm_dir = str(
            SRC_DIR / "externals" / "torch-mlir" / "externals" / "llvm-project" / "llvm"
        )
        cmake_config_args = [
            f"cmake",
            f"-GNinja",
            f"-DCMAKE_BUILD_TYPE=Release",
            f"-DPython3_FIND_VIRTUALENV=ONLY",
            f"-DLLVM_ENABLE_PROJECTS=mlir",
            f"-DLLVM_EXTERNAL_PROJECTS='torch-mlir;mpact'",
            f"-DLLVM_EXTERNAL_TORCH_MLIR_SOURCE_DIR='{SRC_DIR}/externals/torch-mlir'",
            f"-DLLVM_EXTERNAL_MPACT_SOURCE_DIR='{SRC_DIR}'",
            f"-DLLVM_TARGETS_TO_BUILD=host",
            f"-DMLIR_ENABLE_BINDINGS_PYTHON=ON",
            # Optimization options for building wheels.
            f"-DCMAKE_VISIBILITY_INLINES_HIDDEN=ON",
            f"-DCMAKE_C_VISIBILITY_PRESET=hidden",
            f"-DCMAKE_CXX_VISIBILITY_PRESET=hidden",
            f"{llvm_dir}",
        ]

        cmake_build_args = [
            f"cmake",
            f"--build",
            f".",
            f"--target",
            f"MPACTPythonModules",
            f"MPACTBenchmarkPythonModules",
        ]

        try:
            subprocess.check_call(cmake_config_args, cwd=cmake_build_dir)
            subprocess.check_call(cmake_build_args, cwd=cmake_build_dir)
        except subprocess.CalledProcessError as e:
            print("cmake build failed with\n", e)
            print("debug by follow cmake command:")
            sys.exit(e.returncode)
        finally:
            print(f"cmake config: {' '.join(cmake_config_args)}")
            print(f"cmake build: {' '.join(cmake_build_args)}")
            print(f"cmake workspace: {cmake_build_dir}")
            print(SRC_DIR)

    def run(self):
        target_dir = self.build_lib
        cmake_build_dir = MPACT_CMAKE_BUILD_DIR
        if not cmake_build_dir:
            cmake_build_dir = os.path.abspath(os.path.join(target_dir, "..", "build"))

        python_package_dir = os.path.join(
            cmake_build_dir, "tools", "mpact", "python_packages", "mpact"
        )
        if not MPACT_CMAKE_ALREADY_BUILT:
            os.makedirs(cmake_build_dir, exist_ok=True)
            cmake_cache_file = os.path.join(cmake_build_dir, "CMakeCache.txt")
            if os.path.exists(cmake_cache_file):
                os.remove(cmake_cache_file)
            # NOTE: With repeated builds for different Python versions, the
            # prior version binaries will continue to accumulate. Here we just
            # delete the directory where we build native extensions to keep
            # this from happening but still take advantage of most of the
            # build cache.
            mlir_libs_dir = os.path.join(python_package_dir, "mpact", "_mlir_libs")
            if os.path.exists(mlir_libs_dir):
                print(f"Removing _mlir_mlibs dir to force rebuild: {mlir_libs_dir}")
                shutil.rmtree(mlir_libs_dir)
            else:
                print(f"Not removing _mlir_libs dir (does not exist): {mlir_libs_dir}")
            self.cmake_build(cmake_build_dir)

        if os.path.exists(target_dir):
            shutil.rmtree(target_dir, ignore_errors=False, onerror=None)

        shutil.copytree(python_package_dir, target_dir, symlinks=False)


class CMakeExtension(Extension):
    def __init__(self, name, sourcedir=""):
        Extension.__init__(self, name, sources=[])
        self.sourcedir = os.path.abspath(sourcedir)


class NoopBuildExtension(build_ext):
    def build_extension(self, ext):
        pass


with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()


# Requires and extension modules depend on whether building PyTorch
# extensions.
INSTALL_REQUIRES = [
    "numpy",
    "packaging",
]
EXT_MODULES = [
    CMakeExtension("mpact._mlir_libs._mpact"),
]

setup(
    name="mpact",
    version=f"{PACKAGE_VERSION}",
    author="Reid Tatge",
    author_email="tatge@google.com",
    description="MPACT retargetable ML compiler",
    long_description=long_description,
    long_description_content_type="text/markdown",
    include_package_data=True,
    cmdclass={
        "build": CustomBuild,
        "built_ext": NoopBuildExtension,
        "build_py": CMakeBuild,
    },
    ext_modules=EXT_MODULES,
    python_requires=">=3.8",
    install_requires=INSTALL_REQUIRES,
    zip_safe=False,
)
