# -*- coding: ascii -*-
#
# Copyright 2007, 2008, 2009, 2010, 2011
# Andr\xe9 Malo or his licensors, as applicable
#
# 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.
"""
===================
 C extension tools
===================

C extension tools.
"""
__author__ = "Andr\xe9 Malo"
__docformat__ = "restructuredtext en"
__test__ = False

from distutils import core as _core
from distutils import errors as _distutils_errors
from distutils import log
import os as _os
import posixpath as _posixpath
import shutil as _shutil
import tempfile as _tempfile

from _setup import commands as _commands

def _install_finalizer(installer):
    if installer.without_c_extensions:
        installer.distribution.ext_modules = []

def _build_finalizer(builder):
    if builder.without_c_extensions:
        builder.extensions = []


class Extension(_core.Extension):
    """
    Extension with prerequisite check interface

    If your check is cacheable (during the setup run), override
    `cached_check_prerequisites`, `check_prerequisites` otherwise.

    :IVariables:
      `cached_check` : ``bool``
        The cached check result
    """
    cached_check = None

    def __init__(self, *args, **kwargs):
        """ Initialization """
        if 'depends' in kwargs:
            self.depends = kwargs['depends'] or []
        else:
            self.depends = []
        _core.Extension.__init__(self, *args, **kwargs)

        # add include path
        included = _posixpath.join('_setup', 'include')
        if included not in self.include_dirs:
            self.include_dirs.append(included)

        # add cext.h to the dependencies
        cext_h = _posixpath.join(included, 'cext.h')
        if cext_h not in self.depends:
            self.depends.append(cext_h)

        _commands.add_option('install_lib', 'without-c-extensions',
            help_text='Don\'t install C extensions',
            inherit='install',
        )
        _commands.add_finalizer('install_lib', 'c-extensions',
            _install_finalizer
        )
        _commands.add_option('build_ext', 'without-c-extensions',
            help_text='Don\'t build C extensions',
            inherit=('build', 'install_lib'),
        )
        _commands.add_finalizer('build_ext', 'c-extensions', _build_finalizer)

    def check_prerequisites(self, build):
        """
        Check prerequisites

        The check should cover all dependencies needed for the extension to
        be built and run. The method can do the following:

        - return a false value: the extension will be built
        - return a true value: the extension will be skipped. This is useful
          for optional extensions
        - raise an exception. This is useful for mandatory extensions

        If the check result is cacheable (during the setup run), override
        `cached_check_prerequisites` instead.

        :Parameters:
          `build` : `BuildExt`
            The extension builder

        :Return: Skip the extension?
        :Rtype: ``bool``
        """
        if self.cached_check is None:
            log.debug("PREREQ check for %s" % self.name)
            self.cached_check = self.cached_check_prerequisites(build)
        else:
            log.debug("PREREQ check for %s (cached)" % self.name)
        return self.cached_check

    def cached_check_prerequisites(self, build):
        """
        Check prerequisites

        The check should cover all dependencies needed for the extension to
        be built and run. The method can do the following:

        - return a false value: the extension will be built
        - return a true value: the extension will be skipped. This is useful
          for optional extensions
        - raise an exception. This is useful for mandatory extensions

        If the check result is *not* cacheable (during the setup run),
        override `check_prerequisites` instead.

        :Parameters:
          `build` : `BuildExt`
            The extension builder

        :Return: Skip the extension?
        :Rtype: ``bool``
        """
        # pylint: disable = W0613
        log.debug("Nothing to check for %s!" % self.name)
        return False


class ConfTest(object):
    """
    Single conftest abstraction

    :IVariables:
      `_tempdir` : ``str``
        The tempdir created for this test

      `src` : ``str``
        Name of the source file

      `target` : ``str``
        Target filename

      `compiler` : ``CCompiler``
        compiler instance

      `obj` : ``list``
        List of object filenames (``[str, ...]``)
    """
    _tempdir = None

    def __init__(self, build, source):
        """
        Initialization

        :Parameters:
          `build` : ``distuils.command.build_ext.build_ext``
            builder instance

          `source` : ``str``
            Source of the file to compile
        """
        self._tempdir = tempdir = _tempfile.mkdtemp()
        src = _os.path.join(tempdir, 'conftest.c')
        fp = open(src, 'w', encoding='utf-8')
        try:
            fp.write(source)
        finally:
            fp.close()
        self.src = src
        self.compiler = compiler = build.compiler
        self.target = _os.path.join(tempdir, 'conftest')
        self.obj = compiler.object_filenames([src], output_dir=tempdir)

    def __del__(self):
        """ Destruction """
        self.destroy()

    def destroy(self):
        """ Destroy the conftest leftovers on disk """
        tempdir, self._tempdir = self._tempdir, None
        if tempdir is not None:
            _shutil.rmtree(tempdir)

    def compile(self, **kwargs):
        """
        Compile the conftest

        :Parameters:
          `kwargs` : ``dict``
            Optional keyword parameters for the compiler call

        :Return: Was the compilation successful?
        :Rtype: ``bool``
        """
        kwargs['output_dir'] = self._tempdir
        try:
            self.compiler.compile([self.src], **kwargs)
        except _distutils_errors.CompileError:
            return False
        return True

    def link(self, **kwargs):
        r"""
        Link the conftest

        Before you can link the conftest objects they need to be `compile`\d.

        :Parameters:
          `kwargs` : ``dict``
            Optional keyword parameters for the linker call

        :Return: Was the linking successful?
        :Rtype: ``bool``
        """
        try:
            self.compiler.link_executable(self.obj, self.target, **kwargs)
        except _distutils_errors.LinkError:
            return False
        return True

    def pipe(self, mode="r"):
        r"""
        Execute the conftest binary and connect to it using a pipe

        Before you can pipe to or from the conftest binary it needs to
        be `link`\ed.

        :Parameters:
          `mode` : ``str``
            Pipe mode - r/w

        :Return: The open pipe
        :Rtype: ``file``
        """
        return _os.popen(self.compiler.executable_filename(self.target), mode)
