from distutils.core import setup
# Use "Extension" from Cython.Distutils so that "cython_directives" works.
# from distutils.extension import Extension
from Cython.Distutils import build_ext, Extension
import sys
import platform
from Cython.Compiler import Options
import Cython
import os
import struct

print("Cython version: %s" % Cython.__version__)

if len(sys.argv) > 1 and "--fast" in sys.argv:
    sys.argv.remove("--fast")
    # Fast mode disables optimization flags
    FAST = True
    print("FAST mode On")
    COMPILE_OPTIMIZE_FLAGS = ['-flto', '-std=gnu++11']
    LINK_OPTIMIZE_FLAGS = ['-flto']
else:
    FAST = False
    # Fix "ImportError ... undefined symbol ..." caused by CEF's include/base/
    # headers by adding the -flto flag (Issue #230). Unfortunately -flto
    # prolongs compilation time significantly.
    # More on the other flags: https://stackoverflow.com/questions/6687630/
    COMPILE_OPTIMIZE_FLAGS = ['-flto', '-fdata-sections', '-ffunction-sections',
                              '-std=gnu++11']
    LINK_OPTIMIZE_FLAGS = ['-flto', '-Wl,--gc-sections']


# Architecture and OS postfixes
ARCH32 = (8 * struct.calcsize('P') == 32)
ARCH64 = (8 * struct.calcsize('P') == 64)
OS_POSTFIX = ("win" if platform.system() == "Windows" else
              "linux" if platform.system() == "Linux" else
              "mac" if platform.system() == "Darwin" else "unknown")
OS_POSTFIX2 = "unknown"
if OS_POSTFIX == "win":
    OS_POSTFIX2 = "win32" if ARCH32 else "win64"
elif OS_POSTFIX == "mac":
    OS_POSTFIX2 = "mac32" if ARCH32 else "mac64"
elif OS_POSTFIX == "linux":
    OS_POSTFIX2 = "linux32" if ARCH32 else "linux64"

# Directories
SETUP_DIR = os.path.abspath(os.path.dirname(__file__))
LINUX_DIR = os.path.abspath(os.path.join(SETUP_DIR, ".."))
SRC_DIR = os.path.abspath(os.path.join(LINUX_DIR, ".."))
CEFPYTHON_DIR = os.path.abspath(os.path.join(SRC_DIR, ".."))
BUILD_DIR = os.path.abspath(os.path.join(CEFPYTHON_DIR, "build"))
CEF_BINARY = os.path.abspath(os.path.join(BUILD_DIR, "cef_"+OS_POSTFIX2))
CEFPYTHON_BINARY = os.path.abspath(os.path.join(BUILD_DIR,
                                                "cefpython_"+OS_POSTFIX2))

# Stop on first error, otherwise hundreds of errors appear in the console.
Options.fast_fail = True

# Python version string: "27" or "32".
PYTHON_VERSION = str(sys.version_info.major) + str(sys.version_info.minor)


def CompileTimeConstants():

    print("Generating: compile_time_constants.pxi")
    with open("./../../compile_time_constants.pxi", "w") as fd:
        fd.write('# This file was generated by setup.py\n')
        # A way around Python 3.2 bug: UNAME_SYSNAME is not set.
        fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0])
        fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major)

CompileTimeConstants()

ext_modules = [Extension(

    "cefpython_py%s" % PYTHON_VERSION,
    ["cefpython.pyx"],

    # Ignore the warning in the console:
    # > C:\Python27\lib\distutils\extension.py:133: UserWarning:
    # > Unknown Extension options: 'cython_directives' warnings.warn(msg)
    cython_directives={
        # Any conversion to unicode must be explicit using .decode().
        "c_string_type": "bytes",
        "c_string_encoding": "utf-8",
    },

    language='c++',
    include_dirs=[
        r'./../',
        r'./../../',
        r'./../../common/',
        r'./../../extern/',
        r'./../../extern/cef/',
        '/usr/include/gtk-2.0',
        '/usr/include/glib-2.0',
        '/usr/include/gtk-unix-print-2.0',
        '/usr/include/cairo',
        '/usr/include/pango-1.0',
        '/usr/include/gdk-pixbuf-2.0',
        '/usr/include/atk-1.0',
        # Ubuntu
        '/usr/lib/x86_64-linux-gnu/gtk-2.0/include',
        '/usr/lib/x86_64-linux-gnu/gtk-unix-print-2.0',
        '/usr/lib/x86_64-linux-gnu/glib-2.0/include',
        '/usr/lib/i386-linux-gnu/gtk-2.0/include',
        '/usr/lib/i386-linux-gnu/gtk-unix-print-2.0',
        '/usr/lib/i386-linux-gnu/glib-2.0/include',
        # Fedora
        '/usr/lib64/gtk-2.0/include',
        '/usr/lib64/gtk-unix-print-2.0',
        '/usr/lib64/glib-2.0/include',
        '/usr/lib/gtk-2.0/include',
        '/usr/lib/gtk-2.0/gtk-unix-print-2.0',
        '/usr/lib/glib-2.0/include',
    ],

    library_dirs=[
        os.path.join(CEF_BINARY, "lib"),
        r'./../../client_handler/',
        r'./../../subprocess/',  # libcefpythonapp
        r'./../../cpp_utils/'
    ],

    # Static libraries only. Order is important, if library A depends on B,
    # then B must be included before A.
    libraries=[
        'X11',
        'gobject-2.0',
        'glib-2.0',
        'gtk-x11-2.0',
        # CEF and CEF Python libraries
        'cef_dll_wrapper',
        'cefpythonapp',
        'client_handler',
        'cpp_utils',
    ],

    # When you put "./" in here, loading of libcef.so will only work when
    # running scripts from the same directory that libcef.so resides in.
    # runtime_library_dirs=[
    #    './'
    # ],

    extra_compile_args=COMPILE_OPTIMIZE_FLAGS,
    extra_link_args=LINK_OPTIMIZE_FLAGS,

    # Defining macros:
    # define_macros = [("UNICODE","1"), ("_UNICODE","1"), ]
)]

setup(
    name='cefpython_py%s' % PYTHON_VERSION,
    cmdclass={'build_ext': build_ext},
    ext_modules=ext_modules
)
