# Copyright 2013-2017 The Meson development team

# Licensed 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.

# This file contains the detection logic for miscellaneous external dependencies.

import glob
import os

from .. import mlog
from .. import mesonlib
from ..environment import detect_cpu_family

from .base import (DependencyException, ExternalDependency)

# On windows 3 directory layouts are supported:
# * The default layout (versioned) installed:
#   - $BOOST_ROOT/include/boost-x_x/boost/*.hpp
#   - $BOOST_ROOT/lib/*.lib
# * The non-default layout (system) installed:
#   - $BOOST_ROOT/include/boost/*.hpp
#   - $BOOST_ROOT/lib/*.lib
# * The pre-built binaries from sf.net:
#   - $BOOST_ROOT/boost/*.hpp
#   - $BOOST_ROOT/lib<arch>-<compiler>/*.lib where arch=32/64 and compiler=msvc-14.1
#
# Note that we should also try to support:
# mingw-w64 / Windows : libboost_<module>-mt.a            (location = <prefix>/mingw64/lib/)
#                       libboost_<module>-mt.dll.a
#
# Library names supported:
#   - libboost_<module>-<compiler>-mt-gd-x_x.lib (static)
#   - boost_<module>-<compiler>-mt-gd-x_x.lib|.dll (shared)
#   - libboost_<module>.lib (static)
#   - boost_<module>.lib|.dll (shared)
#   where compiler is vc141 for example.
#
# NOTE: -gd means runtime and build time debugging is on
#       -mt means threading=multi
#
# The `modules` argument accept library names. This is because every module that
# has libraries to link against also has multiple options regarding how to
# link. See for example:
# * http://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/boost_test/usage_variants.html
# * http://www.boost.org/doc/libs/1_65_1/doc/html/stacktrace/configuration_and_build.html
# * http://www.boost.org/doc/libs/1_65_1/libs/math/doc/html/math_toolkit/main_tr1.html

# **On Unix**, official packaged versions of boost libraries follow the following schemes:
#
# Linux / Debian:   libboost_<module>.so -> libboost_<module>.so.1.66.0
# Linux / Red Hat:  libboost_<module>.so -> libboost_<module>.so.1.66.0
# Linux / OpenSuse: libboost_<module>.so -> libboost_<module>.so.1.66.0
# Win   / Cygwin:   libboost_<module>.dll.a                                 (location = /usr/lib)
#                   libboost_<module>.a
#                   cygboost_<module>_1_64.dll                              (location = /usr/bin)
# Mac   / homebrew: libboost_<module>.dylib + libboost_<module>-mt.dylib    (location = /usr/local/lib)
# Mac   / macports: libboost_<module>.dylib + libboost_<module>-mt.dylib    (location = /opt/local/lib)
#
# Its not clear that any other abi tags (e.g. -gd) are used in official packages.
#
# On Linux systems, boost libs have multithreading support enabled, but without the -mt tag.
#
# Boost documentation recommends using complex abi tags like "-lboost_regex-gcc34-mt-d-1_36".
# (See http://www.boost.org/doc/libs/1_66_0/more/getting_started/unix-variants.html#library-naming)
# However, its not clear that any Unix distribution follows this scheme.
# Furthermore, the boost documentation for unix above uses examples from windows like
#   "libboost_regex-vc71-mt-d-x86-1_34.lib", so apparently the abi tags may be more aimed at windows.
#
# Probably we should use the linker search path to decide which libraries to use.  This will
# make it possible to find the macports boost libraries without setting BOOST_ROOT, and will
# also mean that it would be possible to use user-installed boost libraries when official
# packages are installed.
#
# We thus follow the following strategy:
# 1. Look for libraries using compiler.find_library( )
#   1.1 On Linux, just look for boost_<module>
#   1.2 On other systems (e.g. Mac) look for boost_<module>-mt if multithreading.
#   1.3 Otherwise look for boost_<module>
# 2. Fall back to previous approach
#   2.1. Search particular directories.
#   2.2. Find boost libraries with unknown suffixes using file-name globbing.

# TODO: Unix: Don't assume we know where the boost dir is, rely on -Idir and -Ldir being set.
# TODO: Allow user to specify suffix in BOOST_SUFFIX, or add specific options like BOOST_DEBUG for 'd' for debug.

class BoostDependency(ExternalDependency):
    def __init__(self, environment, kwargs):
        super().__init__('boost', environment, 'cpp', kwargs)
        self.need_static_link = ['boost_exception', 'boost_test_exec_monitor']
        self.is_debug = environment.coredata.get_builtin_option('buildtype').startswith('debug')
        threading = kwargs.get("threading", "multi")
        self.is_multithreading = threading == "multi"

        self.requested_modules = self.get_requested(kwargs)

        self.boost_root = None
        self.boost_roots = []
        self.incdir = None
        self.libdir = None

        if 'BOOST_ROOT' in os.environ:
            self.boost_root = os.environ['BOOST_ROOT']
            self.boost_roots = [self.boost_root]
            if not os.path.isabs(self.boost_root):
                raise DependencyException('BOOST_ROOT must be an absolute path.')
        if 'BOOST_INCLUDEDIR' in os.environ:
            self.incdir = os.environ['BOOST_INCLUDEDIR']
        if 'BOOST_LIBRARYDIR' in os.environ:
            self.libdir = os.environ['BOOST_LIBRARYDIR']

        if self.boost_root is None:
            if mesonlib.for_windows(self.want_cross, self.env):
                self.boost_roots = self.detect_win_roots()
            else:
                self.boost_roots = self.detect_nix_roots()

        if self.incdir is None:
            if mesonlib.for_windows(self.want_cross, self.env):
                self.incdir = self.detect_win_incdir()
            else:
                self.incdir = self.detect_nix_incdir()

        if self.check_invalid_modules():
            self.log_fail()
            return

        mlog.debug('Boost library root dir is', mlog.bold(self.boost_root))
        mlog.debug('Boost include directory is', mlog.bold(self.incdir))

        # 1. check if we can find BOOST headers.
        self.detect_headers_and_version()

        # 2. check if we can find BOOST libraries.
        if self.is_found:
            self.detect_lib_modules()
            mlog.debug('Boost library directory is', mlog.bold(self.libdir))

        # 3. Report success or failure
        if self.is_found:
            self.log_success()
        else:
            self.log_fail()

    def check_invalid_modules(self):
        invalid_modules = [c for c in self.requested_modules if 'boost_' + c not in BOOST_LIBS]

        # previous versions of meson allowed include dirs as modules
        remove = []
        for m in invalid_modules:
            if m in BOOST_DIRS:
                mlog.warning('Requested boost library', mlog.bold(m), 'that doesn\'t exist. '
                             'This will be an error in the future')
                remove.append(m)

        self.requested_modules = [x for x in self.requested_modules if x not in remove]
        invalid_modules = [x for x in invalid_modules if x not in remove]

        if invalid_modules:
            mlog.error('Invalid Boost modules: ' + ', '.join(invalid_modules))
            return True
        else:
            return False

    def log_fail(self):
        module_str = ', '.join(self.requested_modules)
        mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))

    def log_success(self):
        module_str = ', '.join(self.requested_modules)
        if self.boost_root:
            info = self.version + ', ' + self.boost_root
        else:
            info = self.version
        mlog.log('Dependency Boost (%s) found:' % module_str, mlog.green('YES'), info)

    def detect_nix_roots(self):
        return [os.path.abspath(os.path.join(x, '..'))
                for x in self.clib_compiler.get_default_include_dirs()]

    def detect_win_roots(self):
        res = []
        # Where boost documentation says it should be
        globtext = 'C:\\Program Files\\boost\\boost_*'
        files = glob.glob(globtext)
        res.extend(files)

        # Where boost built from source actually installs it
        if os.path.isdir('C:\\Boost'):
            res.append('C:\\Boost')

        # Where boost prebuilt binaries are
        globtext = 'C:\\local\\boost_*'
        files = glob.glob(globtext)
        res.extend(files)
        return res

    def detect_nix_incdir(self):
        if self.boost_root:
            return os.path.join(self.boost_root, 'include')
        return None

    # FIXME: Should pick a version that matches the requested version
    # Returns the folder that contains the boost folder.
    def detect_win_incdir(self):
        for root in self.boost_roots:
            globtext = os.path.join(root, 'include', 'boost-*')
            incdirs = glob.glob(globtext)
            if len(incdirs) > 0:
                return incdirs[0]
            incboostdir = os.path.join(root, 'include', 'boost')
            if os.path.isdir(incboostdir):
                return os.path.join(root, 'include')
            incboostdir = os.path.join(root, 'boost')
            if os.path.isdir(incboostdir):
                return root
        return None

    def get_compile_args(self):
        args = []
        include_dir = self.incdir

        # Use "-isystem" when including boost headers instead of "-I"
        # to avoid compiler warnings/failures when "-Werror" is used

        # Careful not to use "-isystem" on default include dirs as it
        # breaks some of the headers for certain gcc versions

        # For example, doing g++ -isystem /usr/include on a simple
        # "int main()" source results in the error:
        # "/usr/include/c++/6.3.1/cstdlib:75:25: fatal error: stdlib.h: No such file or directory"

        # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129
        # and http://stackoverflow.com/questions/37218953/isystem-on-a-system-include-directory-causes-errors
        # for more details

        if include_dir and include_dir not in self.clib_compiler.get_default_include_dirs():
            args.append("".join(self.clib_compiler.get_include_args(include_dir, True)))
        return args

    def get_requested(self, kwargs):
        candidates = mesonlib.extract_as_list(kwargs, 'modules')
        for c in candidates:
            if not isinstance(c, str):
                raise DependencyException('Boost module argument is not a string.')
        return candidates

    def detect_headers_and_version(self):
        try:
            version = self.clib_compiler.get_define('BOOST_LIB_VERSION', '#include <boost/version.hpp>', self.env, self.get_compile_args(), [])
        except mesonlib.EnvironmentException:
            return
        except TypeError:
            return
        # Remove quotes
        version = version[1:-1]
        # Fix version string
        self.version = version.replace('_', '.')
        self.is_found = True

    def detect_lib_modules(self):
        self.lib_modules = {}

        # 1. Try to find modules using compiler.find_library( )
        if self.find_libraries_with_abi_tags(self.abi_tags()):
            pass
        # 2. Fall back to the old method
        else:
            if mesonlib.for_windows(self.want_cross, self.env):
                self.detect_lib_modules_win()
            else:
                self.detect_lib_modules_nix()

        # 3. Check if we can find the modules
        for m in self.requested_modules:
            if 'boost_' + m not in self.lib_modules:
                mlog.debug('Requested Boost library {!r} not found'.format(m))
                self.is_found = False

    def modname_from_filename(self, filename):
        modname = os.path.basename(filename)
        modname = modname.split('.', 1)[0]
        modname = modname.split('-', 1)[0]
        if modname.startswith('libboost'):
            modname = modname[3:]
        return modname

    def compiler_tag(self):
        tag = None
        compiler = self.env.detect_cpp_compiler(self.want_cross)
        if mesonlib.for_windows(self.want_cross, self.env):
            if compiler.get_id() == 'msvc':
                comp_ts_version = compiler.get_toolset_version()
                compiler_ts = comp_ts_version.split('.')
                # FIXME - what about other compilers?
                tag = '-vc{}{}'.format(compiler_ts[0], compiler_ts[1])
            else:
                tag = ''
        return tag

    def threading_tag(self):
        if not self.is_multithreading:
            return ''

        if mesonlib.for_darwin(self.want_cross, self.env):
            # - Mac:      requires -mt for multithreading, so should not fall back to non-mt libraries.
            return '-mt'
        elif mesonlib.for_windows(self.want_cross, self.env):
            # - Windows:  requires -mt for multithreading, so should not fall back to non-mt libraries.
            return '-mt'
        else:
            # - Linux:    leaves off -mt but libraries are multithreading-aware.
            # - Cygwin:   leaves off -mt but libraries are multithreading-aware.
            return ''

    def version_tag(self):
        return '-' + self.version.replace('.', '_')

    def debug_tag(self):
        return '-gd' if self.is_debug else ''

    def versioned_abi_tag(self):
        return self.compiler_tag() + self.threading_tag() + self.debug_tag() + self.version_tag()

    # FIXME - how to handle different distributions, e.g. for Mac? Currently we handle homebrew and macports, but not fink.
    def abi_tags(self):
        if mesonlib.for_windows(self.want_cross, self.env):
            return [self.versioned_abi_tag(), self.threading_tag()]
        else:
            return [self.threading_tag()]

    def sourceforge_dir(self):
        if self.env.detect_cpp_compiler(self.want_cross).get_id() != 'msvc':
            return None
        comp_ts_version = self.env.detect_cpp_compiler(self.want_cross).get_toolset_version()
        arch = detect_cpu_family(self.env.coredata.compilers)
        if arch == 'x86':
            return 'lib32-msvc-{}'.format(comp_ts_version)
        elif arch == 'x86_64':
            return 'lib64-msvc-{}'.format(comp_ts_version)
        else:
            # Does anyone do Boost cross-compiling to other archs on Windows?
            return None

    def find_libraries_with_abi_tag(self, tag):

        # All modules should have the same tag
        self.lib_modules = {}

        all_found = True

        for module in self.requested_modules:
            libname = 'boost_' + module + tag

            args = self.clib_compiler.find_library(libname, self.env, self.extra_lib_dirs())
            if args is None:
                mlog.debug("Couldn\'t find library '{}' for boost module '{}'  (ABI tag = '{}')".format(libname, module, tag))
                all_found = False
            else:
                mlog.debug('Link args for boost module "{}" are {}'.format(module, args))
                self.lib_modules['boost_' + module] = args

        return all_found

    def find_libraries_with_abi_tags(self, tags):
        for tag in tags:
            if self.find_libraries_with_abi_tag(tag):
                return True
        return False

    def detect_lib_modules_win(self):
        if not self.libdir:
            # The libdirs in the distributed binaries (from sf)
            lib_sf = self.sourceforge_dir()

            if self.boost_root:
                roots = [self.boost_root]
            else:
                roots = self.boost_roots
            for root in roots:
                # The default libdir when building
                libdir = os.path.join(root, 'lib')
                if os.path.isdir(libdir):
                    self.libdir = libdir
                    break
                if lib_sf:
                    full_path = os.path.join(root, lib_sf)
                    if os.path.isdir(full_path):
                        self.libdir = full_path
                        break

        if not self.libdir:
            return

        for name in self.need_static_link:
            # FIXME - why are we only looking for *.lib? Mingw provides *.dll.a and *.a
            libname = 'lib' + name + self.versioned_abi_tag() + '.lib'
            if os.path.isfile(os.path.join(self.libdir, libname)):
                self.lib_modules[self.modname_from_filename(libname)] = [libname]
            else:
                libname = "lib{}.lib".format(name)
                if os.path.isfile(os.path.join(self.libdir, libname)):
                    self.lib_modules[name[3:]] = [libname]

        # globber1 applies to a layout=system installation
        # globber2 applies to a layout=versioned installation
        globber1 = 'libboost_*' if self.static else 'boost_*'
        globber2 = globber1 + self.versioned_abi_tag()
        # FIXME - why are we only looking for *.lib? Mingw provides *.dll.a and *.a
        globber2_matches = glob.glob(os.path.join(self.libdir, globber2 + '.lib'))
        for entry in globber2_matches:
            fname = os.path.basename(entry)
            self.lib_modules[self.modname_from_filename(fname)] = [fname]
        if len(globber2_matches) == 0:
            # FIXME - why are we only looking for *.lib? Mingw provides *.dll.a and *.a
            for entry in glob.glob(os.path.join(self.libdir, globber1 + '.lib')):
                if self.static:
                    fname = os.path.basename(entry)
                    self.lib_modules[self.modname_from_filename(fname)] = [fname]

    def detect_lib_modules_nix(self):
        if self.static:
            libsuffix = 'a'
        elif mesonlib.for_darwin(self.want_cross, self.env):
            libsuffix = 'dylib'
        else:
            libsuffix = 'so'

        globber = 'libboost_*.{}'.format(libsuffix)
        if self.libdir:
            libdirs = [self.libdir]
        elif self.boost_root is None:
            libdirs = mesonlib.get_library_dirs()
        else:
            libdirs = [os.path.join(self.boost_root, 'lib')]
        for libdir in libdirs:
            for name in self.need_static_link:
                libname = 'lib{}.a'.format(name)
                if os.path.isfile(os.path.join(libdir, libname)):
                    self.lib_modules[name] = [libname]
            for entry in glob.glob(os.path.join(libdir, globber)):
                # I'm not 100% sure what to do here. Some distros
                # have modules such as thread only as -mt versions.
                # On debian all packages are built threading=multi
                # but not suffixed with -mt.
                # FIXME: implement detect_lib_modules_{debian, redhat, ...}
                # FIXME: this wouldn't work with -mt-gd either. -BDR
                if self.is_multithreading and mesonlib.is_debianlike():
                    pass
                elif self.is_multithreading and entry.endswith('-mt.{}'.format(libsuffix)):
                    pass
                elif not entry.endswith('-mt.{}'.format(libsuffix)):
                    pass
                else:
                    continue
                modname = self.modname_from_filename(entry)
                if modname not in self.lib_modules:
                    self.lib_modules[modname] = [entry]

    def extra_lib_dirs(self):
        if self.libdir:
            return [self.libdir]
        elif self.boost_root:
            return [os.path.join(self.boost_root, 'lib')]
        return []

    def get_link_args(self, **kwargs):
        args = []
        for d in self.extra_lib_dirs():
            args += self.clib_compiler.get_linker_search_args(d)
        for lib in self.requested_modules:
            args += self.lib_modules['boost_' + lib]
        return args

    def get_sources(self):
        return []

    def need_threads(self):
        return 'thread' in self.requested_modules


# Generated with boost_names.py
BOOST_LIBS = [
    'boost_atomic',
    'boost_chrono',
    'boost_chrono',
    'boost_container',
    'boost_context',
    'boost_coroutine',
    'boost_date_time',
    'boost_exception',
    'boost_fiber',
    'boost_filesystem',
    'boost_graph',
    'boost_iostreams',
    'boost_locale',
    'boost_log',
    'boost_log_setup',
    'boost_math_tr1',
    'boost_math_tr1f',
    'boost_math_tr1l',
    'boost_math_c99',
    'boost_math_c99f',
    'boost_math_c99l',
    'boost_math_tr1',
    'boost_math_tr1f',
    'boost_math_tr1l',
    'boost_math_c99',
    'boost_math_c99f',
    'boost_math_c99l',
    'boost_math_tr1',
    'boost_math_tr1f',
    'boost_math_tr1l',
    'boost_math_c99',
    'boost_math_c99f',
    'boost_math_c99l',
    'boost_math_tr1',
    'boost_math_tr1f',
    'boost_math_tr1l',
    'boost_math_c99',
    'boost_math_c99f',
    'boost_math_c99l',
    'boost_math_tr1',
    'boost_math_tr1f',
    'boost_math_tr1l',
    'boost_math_c99',
    'boost_math_c99f',
    'boost_math_c99l',
    'boost_math_tr1',
    'boost_math_tr1f',
    'boost_math_tr1l',
    'boost_math_c99',
    'boost_math_c99f',
    'boost_math_c99l',
    'boost_mpi',
    'boost_program_options',
    'boost_python',
    'boost_python3',
    'boost_numpy',
    'boost_numpy3',
    'boost_random',
    'boost_regex',
    'boost_serialization',
    'boost_wserialization',
    'boost_signals',
    'boost_stacktrace_noop',
    'boost_stacktrace_backtrace',
    'boost_stacktrace_addr2line',
    'boost_stacktrace_basic',
    'boost_stacktrace_windbg',
    'boost_stacktrace_windbg_cached',
    'boost_system',
    'boost_prg_exec_monitor',
    'boost_test_exec_monitor',
    'boost_unit_test_framework',
    'boost_thread',
    'boost_timer',
    'boost_type_erasure',
    'boost_wave'
]

BOOST_DIRS = [
    'lambda',
    'optional',
    'convert',
    'system',
    'uuid',
    'archive',
    'align',
    'timer',
    'chrono',
    'gil',
    'logic',
    'signals',
    'predef',
    'tr1',
    'multi_index',
    'property_map',
    'multi_array',
    'context',
    'random',
    'endian',
    'circular_buffer',
    'proto',
    'assign',
    'format',
    'math',
    'phoenix',
    'graph',
    'locale',
    'mpl',
    'pool',
    'unordered',
    'core',
    'exception',
    'ptr_container',
    'flyweight',
    'range',
    'typeof',
    'thread',
    'move',
    'spirit',
    'dll',
    'compute',
    'serialization',
    'ratio',
    'msm',
    'config',
    'metaparse',
    'coroutine2',
    'qvm',
    'program_options',
    'concept',
    'detail',
    'hana',
    'concept_check',
    'compatibility',
    'variant',
    'type_erasure',
    'mpi',
    'test',
    'fusion',
    'log',
    'sort',
    'local_function',
    'units',
    'functional',
    'preprocessor',
    'integer',
    'container',
    'polygon',
    'interprocess',
    'numeric',
    'iterator',
    'wave',
    'lexical_cast',
    'multiprecision',
    'utility',
    'tti',
    'asio',
    'dynamic_bitset',
    'algorithm',
    'xpressive',
    'bimap',
    'signals2',
    'type_traits',
    'regex',
    'statechart',
    'parameter',
    'icl',
    'python',
    'lockfree',
    'intrusive',
    'io',
    'pending',
    'geometry',
    'tuple',
    'iostreams',
    'heap',
    'atomic',
    'filesystem',
    'smart_ptr',
    'function',
    'fiber',
    'type_index',
    'accumulators',
    'function_types',
    'coroutine',
    'vmd',
    'date_time',
    'property_tree',
    'bind'
]
