# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import errno
import glob
import os
import shutil
import sys

from setuptools import Extension

class BadAutoconfSubstitutes(ValueError):
    pass

def _get_ac_subst_bool(true_subst, false_subst):
    """
        This function accepts arguments which are supposedly a result
        of substitution by the code in the configure script that
        was generated for a boolean flag.
        It either returns the value of this flag, or fails if the
        combination of these "substitution results" is not valid.

        Usage example.
        - configure.ac:
            AM_CONDITIONAL([FLAG], 0])
            AM_CONDITIONAL([FLAG2], 1)

        - This file (before processing by the configure script):
            >>> __get_ac_subst_bool('@FLAG_TRUE@', '@FLAG_FALSE@')
            True
            >>> __get_ac_subst_bool('@FLAG2_TRUE@', '@FLAG2_FALSE@')
            False
            >>> __get_ac_subst_bool('@BAD_FLAG_TRUE@', '@BAD_FLAG_FALSE@')
            Traceback (most recent call last):
            ...
            BadAutoconfSubstitutes: ...

        Inside workings - what is really going on in this example
        after running the configure script:
            >>> __get_ac_subst_bool('', '#')
            >>> True
            >>> __get_ac_subst_bool('#', '')
            >>> False
            >>> __get_ac_subst_bool('@BAD_FLAG_TRUE@', '@BAD_FLAG_FALSE@')
            Traceback (most recent call last):
            ...
            BadAutoconfSubstitutes: ...
    """
    if true_subst == "" and false_subst == "#":
        return True
    if true_subst == "#" and false_subst == "":
        return False
    raise BadAutoconfSubstitutes(
        "Bad values substitutes were inserted (or nothing were inserted) "
        "into this file by the configure script: %s and %s".format(
            true_subst, false_subst
        )
    )


def cond_multiple_extra_objects(true_subst, false_subst, bundled, system):
    """
        Depending on the provided results of substitution by the configure
        script, return either `bundled` or `system` objects.
        If adding bundled objects, check their existence
        and fail if they are missing.
    """
    use_bundled = _get_ac_subst_bool(true_subst, false_subst)
    if use_bundled:
        for obj in bundled:
            if not os.path.exists(obj):
                raise RuntimeError("{} does not exist.".format(obj))
        return bundled
    return system


def _cond_extra_object(true_subst, false_subst, bundled, system):
    return cond_multiple_extra_objects(true_subst, false_subst,
                                 [bundled], [system])


def _create_module(module_name):
    abs_top_srcdir = '@abs_top_srcdir@'
    abs_top_builddir = '@abs_top_builddir@'

    ext_src_dir = os.path.join(
        'src', 'python', module_name, 'src', 'mesos', module_name)
    ext_common_dir = os.path.join(
        'src', 'python', 'native_common')

    leveldb = os.path.join('3rdparty', 'leveldb-1.19')
    zookeeper = os.path.join('3rdparty', 'zookeeper-3.4.8', 'src', 'c')
    libprocess = os.path.join('3rdparty', 'libprocess')

    # Even though a statically compiled libprocess should include glog,
    # libev, gperftools, and protobuf before installation this isn't the
    # case, so while a libtool managed build will correctly pull in these
    # libraries when building the final result, we need to explicitly
    # include them here (or more precisely, down where we actually include
    # libev.a and libprofiler.a).
    glog = os.path.join('3rdparty', 'glog-0.4.0')
    gperftools = os.path.join('3rdparty', 'gperftools-2.5')
    protobuf = os.path.join('3rdparty', 'protobuf-3.5.0')

    re2 = os.path.join('3rdparty', 're2-2020-07-06')

    # Build the list of source files. Note that each source must be
    # relative to our current directory (where this script lives).
    SOURCES = [
        os.path.join('src', 'mesos', module_name, file)
            for file in os.listdir(os.path.join(abs_top_srcdir, ext_src_dir))
                if file.endswith('.cpp')
    ]

    INCLUDE_DIRS = [
        os.path.join(abs_top_srcdir, 'include'),
        os.path.join(abs_top_builddir, 'include'),
        # Needed for the *.pb.h protobuf includes.
        os.path.join(abs_top_builddir, 'include', 'mesos'),
        os.path.join(abs_top_builddir, 'src'),
        os.path.join(abs_top_builddir, ext_src_dir),
        os.path.join(abs_top_builddir, ext_common_dir),
        os.path.join(abs_top_builddir, protobuf, 'src'),
    ]

    LIBRARY_DIRS = []

    EXTRA_OBJECTS = [
        os.path.join(abs_top_builddir, 'src', '.libs', 'libmesos_no_3rdparty.a'),
        os.path.join(abs_top_builddir, libprocess, '.libs', 'libprocess.a')
    ]

    # For leveldb, we need to check for the presence of libleveldb.a, since
    # it is possible to disable leveldb inside mesos.
    libleveldb = os.path.join(abs_top_builddir, leveldb, 'out-static', 'libleveldb.a')
    EXTRA_OBJECTS += _cond_extra_object(
        "@WITH_BUNDLED_LEVELDB_TRUE@",
        "@WITH_BUNDLED_LEVELDB_FALSE@",
        libleveldb,
        '-lleveldb'
    )
    EXTRA_OBJECTS += _cond_extra_object(
        "@WITH_BUNDLED_ZOOKEEPER_TRUE@",
        "@WITH_BUNDLED_ZOOKEEPER_FALSE@",
        os.path.join(abs_top_builddir, zookeeper, '.libs', 'libzookeeper_mt.a'),
        '-lzookeeper_mt'
    )
    EXTRA_OBJECTS += _cond_extra_object(
        "@WITH_BUNDLED_GLOG_TRUE@",
        "@WITH_BUNDLED_GLOG_FALSE@",
        os.path.join(abs_top_builddir, glog, '.libs', 'libglog.a'),
        '-lglog'
    )
    EXTRA_OBJECTS += _cond_extra_object(
        "@WITH_BUNDLED_PROTOBUF_TRUE@",
        "@WITH_BUNDLED_PROTOBUF_FALSE@",
        os.path.join(abs_top_builddir, protobuf, 'src', '.libs', 'libprotobuf.a'),
        '-lprotobuf'
    )

    EXTRA_OBJECTS += _cond_extra_object(
        "@WITH_BUNDLED_RE2_TRUE@",
        "@WITH_BUNDLED_RE2_FALSE@",
        os.path.join(abs_top_builddir, re2, 'obj', 'libre2.a'),
        '-lre2'
    )

    if '@ENABLE_SECCOMP_ISOLATOR_TRUE@' == '':
        libseccomp = os.path.join('3rdparty', 'libseccomp-2.3.3')
        libseccomp = os.path.join(
            abs_top_builddir, libseccomp, 'src', '.libs', 'libseccomp.a')
        EXTRA_OBJECTS += _cond_extra_object(
            "@WITH_BUNDLED_LIBSECCOMP_TRUE@",
            "@WITH_BUNDLED_LIBSECCOMP_FALSE@",
            libseccomp,
            '-lseccomp'
        )

    # libev is a special case because it needs to be enabled only when
    # libevent *is not* enabled through the top level ./configure.
    #
    # TODO(hartem): this entire block MUST be removed once libev is deprecated
    # in favor of libevent.
    if not _get_ac_subst_bool(
        '@ENABLE_LIBEVENT_TRUE@',
        '@ENABLE_LIBEVENT_FALSE@'
        ):
        libev = os.path.join('3rdparty', 'libev-4.22')
        EXTRA_OBJECTS += _cond_extra_object(
            "@WITH_BUNDLED_LIBEV_TRUE@",
            "@WITH_BUNDLED_LIBEV_FALSE@",
            os.path.join(abs_top_builddir, libev, '.libs', 'libev.a'),
            '-lev'
        )
    else:
        libevent_dir = os.path.join('3rdparty', 'libevent-2.0.22-stable')
        libevent_dir = os.path.join(abs_top_builddir, libevent_dir, '.libs')

        libevent_bundled = [
            os.path.join(libevent_dir, 'libevent_core.a'),
            os.path.join(libevent_dir, 'libevent_pthreads.a'),
        ]
        libevent_system = ['-levent_core', '-levent_pthreads']
        if _get_ac_subst_bool('@ENABLE_SSL_TRUE@', '@ENABLE_SSL_FALSE@'):
            libevent_bundled.append(
                os.path.join(libevent_dir, 'libevent_openssl.a')
            )
            libevent_system.append('-levent_core')

        EXTRA_OBJECTS += cond_multiple_extra_objects(
            "@WITH_BUNDLED_LIBEVENT_TRUE@",
            "@WITH_BUNDLED_LIBEVENT_FALSE@",
            libevent_bundled,
            libevent_system
        )

    # For gperftools, we need to check for the presence of libprofiler.a, since
    # it is possible to disable perftools inside libprocess.
    libprofiler = os.path.join(
        abs_top_builddir, gperftools, '.libs', 'libprofiler.a')

    if os.path.exists(libprofiler):
        EXTRA_OBJECTS.append(libprofiler)


    # We link different grpc library variants based on whether SSL is enabled.
    grpc = os.path.join('3rdparty', 'grpc-1.11.1')
    grpc_variant = '_unsecure' if '@ENABLE_SSL_TRUE@' == '#' else ''
    libgrpcpp = os.path.join(abs_top_builddir, grpc, 'libs', 'opt', 'libgrpc++%s.a' % grpc_variant)
    libgrpc = os.path.join(abs_top_builddir, grpc, 'libs', 'opt', 'libgrpc%s.a' % grpc_variant)
    libgpr = os.path.join(abs_top_builddir, grpc, 'libs', 'opt', 'libgpr.a')

    EXTRA_OBJECTS += cond_multiple_extra_objects(
        "@WITH_BUNDLED_GRPC_TRUE@",
        "@WITH_BUNDLED_GRPC_FALSE@",
        [libgrpcpp, libgrpc, libgpr],
        ['-lgrpc++%s' % grpc_variant, '-lgrpc%s' % grpc_variant, '-lgpr']
    )
    # OSX uses a different linker (llvm-ld) and doesn't support --as-needed
    # TODO(SteveNiemitz): Feature detect --as-needed instead of looking at
    # sys.platform.
    EXTRA_LINK_ARGS = ['-Wl,--as-needed'] if sys.platform != 'darwin' else []

    # Add any flags from LDFLAGS.
    if 'LDFLAGS' in os.environ:
        for flag in os.environ['LDFLAGS'].split():
            EXTRA_LINK_ARGS.append(flag)

    # Add any libraries from LIBS.
    if 'LIBS' in os.environ:
        for library in os.environ['LIBS'].split():
            EXTRA_LINK_ARGS.append(library)

    # Note that we add EXTRA_OBJECTS to our dependency list to make sure
    # that we rebuild this module when one of them changes (e.g.,
    # libprocess).
    mesos_module = \
        Extension('mesos.%s._%s' % (module_name, module_name),
                  sources = SOURCES,
                  include_dirs = INCLUDE_DIRS,
                  library_dirs = LIBRARY_DIRS,
                  extra_objects = EXTRA_OBJECTS,
                  extra_link_args = EXTRA_LINK_ARGS,
                  depends = EXTRA_OBJECTS,
                  language = 'c++',
                  )
    return mesos_module

executor_module = _create_module("executor")
scheduler_module = _create_module("scheduler")
