 # Copyright (C) 2000, 2001, 2013 Gregory Trubetskoy
 # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Apache Software Foundation
 #
 #  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.
 #
 #
 # $Id: setup.py.in 475516 2006-11-16 01:12:40Z grahamd $

from distutils.core import setup, Extension

import sys
import re
import os.path
if sys.version[0] == '2':
    from commands import getoutput
else:
    from subprocess import getoutput

try:
    __file__
except NameError:
    __file__ = '.'

def getmp_rootdir():
    """gets the root directory of the mod_python source tree..."""
    return os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))

def getmp_srcdir():
    """gets the src subdirectory of the mod_python source tree..."""
    return os.path.join(getmp_rootdir(), 'src')

def getmp_includedir():
    """gets the src subdirectory of the mod_python source tree..."""
    return os.path.join(getmp_rootdir(), 'src', 'include')

def getmp_mpdir():
  """gets the mod_python dir"""
  return os.path.join(getmp_rootdir(), 'lib', 'python', 'mod_python')

def getconfigure_option(option_name):
    """gets an option from the config.status file"""
    config_status_file = os.path.join(getmp_rootdir(), 'config.status')
    if not os.path.exists(config_status_file):
        raise AssertionError("config.status not found in expected location (%s)" % config_status_file)
    header = open(config_status_file, 'r')
    r = re.compile(r's,\s*@%s@,\s*(?P<OPTION_STRING>[^,]+),\s*' % (option_name))
    for line in header.readlines():
        m = r.search(line)
        if m is not None:
            return m.group('OPTION_STRING')
    raise AssertionError("unable to find @%s@ definition in %s", (option_name, config_status_file))

def getmp_version():
  return getoutput('./version.sh')

def getapxs_location():
    """finds the location of apxs from the config.status file"""
    return getconfigure_option("APXS")

def getapxs_option(option):
    APXS = getapxs_location()
    return getoutput("%s -q %s" % (APXS, option))

def getapache_srcdir():
    """returns apache src directory"""
    return os.getenv("APACHESRC")

def getapache_includedir():
    """returns apache include directory"""
    apache_srcdir = getapache_srcdir()
    if apache_srcdir is None:
        return getapxs_option("INCLUDEDIR")
    else:
        return os.path.join(getapache_srcdir(), "include")

def getapache_libdir():
    """returns apache lib directory"""
    apache_srcdir = getapache_srcdir()
    if apache_srcdir is None:
        return getapxs_option("LIBDIR")
    else:
        return os.path.join(apache_srcdir, "lib")

def generate_version_py():
    with open(os.path.join(getmp_mpdir(), 'version.py'), 'w') as version_py:
        version_py.write('# THIS FILE IS AUTO-GENERATED BY setup.py\n\n')
        version_py.write('version = "%s"\n' % getmp_version())
        version_py.write('\n# Some build-time constants:\n')
        version_py.write('HTTPD = "/usr/pkg/sbin/httpd"\n')
        version_py.write('HTTPD_VERSION = "2.4.37"\n')
        version_py.write('APR_VERSION = "1.6.5"\n')
        version_py.write('LIBEXECDIR = "/usr/pkg/lib/httpd"\n')
        version_py.write('SYSCONFDIR = ""\n')
        version_py.write('TEST_MOD_PYTHON_SO = "/tmp/pkgbuild/www/ap2-python/work/mod_python-3.5.0/src/mod_python.so" #NB: This is for test.py only\n')
        version_py.write('TESTHOME = "/tmp/pkgbuild/www/ap2-python/work/mod_python-3.5.0/test"\n')
        version_py.write('PYTHON_BIN = "/usr/pkg/bin/python3.5"\n')


VER = getmp_version()

# TODO: improve the intelligence here...
winbuild = ("bdist_wininst" in sys.argv) or (os.name == "nt")

class PSPExtension(Extension):
    """a class that helps build the PSP extension"""
    def __init__(self, source_dir, include_dirs):
        Extension.__init__(self, "mod_python._psp",
                               [os.path.join(source_dir, source_file) for source_file in
                                    ("psp_string.c", "psp_parser.c", "_pspmodule.c")],
                                include_dirs=include_dirs
                           )

        if winbuild:
            self.define_macros.extend([('WIN32', None), ('NDEBUG', None), ('_WINDOWS', None)])

PSPModule = PSPExtension(getmp_srcdir(), [getmp_includedir()])

modpy_src_files = ("mod_python.c", "_apachemodule.c", "connobject.c", "filterobject.c",
                   "hlist.c", "hlistobject.c", "requestobject.c", "serverobject.c", "tableobject.c",
                   "util.c", "finfoobject.c")

class finallist(list):
  """this represents a list that cannot be appended to..."""
  def append(self, object):
      return

class ModPyExtension(Extension):
    """a class that actually builds the mod_python.so extension for Apache (yikes)"""
    def __init__(self, source_dir, include_dirs, library_dirs):
        if winbuild:
            apr1 = 0
            for dir in library_dirs:
                if os.path.exists(os.path.join(dir, 'libapr-1.lib')):
                    apr1 = 1
            if apr1:
                libraries = ['libhttpd', 'libapr-1', 'libaprutil-1', 'ws2_32']
            else:
                libraries = ['libhttpd', 'libapr', 'libaprutil', 'ws2_32']
        else:
            libraries = ['apr-0', 'aprutil-0']

        Extension.__init__(self, "mod_python_so",
            sources = [os.path.join(source_dir, source_file) for source_file in modpy_src_files],
                           include_dirs=include_dirs,
            libraries = libraries,
            library_dirs=library_dirs
                           )
        if winbuild:
            self.define_macros.extend([('WIN32', None),('NDEBUG', None),('_WINDOWS', None)])
            self.sources.append(os.path.join(source_dir, "Version.rc"))
        else:
            # TODO: fix this to autodetect if required...
            self.include_dirs.append("/usr/include/apr-0")
        # this is a hack to prevent build_ext from trying to append "initmod_python" to the export symbols
        self.export_symbols = finallist(self.export_symbols)


if winbuild:

    # build mod_python.so
    ModPyModule = ModPyExtension(getmp_srcdir(), [getmp_includedir(), getapache_includedir()], [getapache_libdir()])

    scripts = ["win32_postinstall.py"]
    # put the mod_python.so file in the Python root ...
    # win32_postinstall.py will pick it up from there...
    # data_files = [("", [(os.path.join(getmp_srcdir(), 'Release', 'mod_python.so'))])]
    data_files = []
    ext_modules = [ModPyModule, PSPModule]

else:

    scripts = []
    data_files = []
    ext_modules = [PSPModule]

import string
from distutils import sysconfig

generate_version_py()

if sys.platform == "darwin":
    if not '-undefined' in sysconfig.get_config_var("LDSHARED").split():
        sysconfig._config_vars["LDSHARED"] = \
                string.replace(sysconfig.get_config_var("LDSHARED"), \
                " -bundle "," -bundle -flat_namespace -undefined suppress ")
        sysconfig._config_vars["BLDSHARED"] = \
                string.replace(sysconfig.get_config_var("BLDSHARED"), \
                " -bundle "," -bundle -flat_namespace -undefined suppress ")

setup(name="mod_python",
      version=VER,
      description="Apache/Python Integration",
      author="Gregory Trubetskoy et al",
      author_email="mod_python@modpython.org",
      url="http://www.modpython.org/",
      packages=["mod_python"],
      package_dir={'mod_python': os.path.join(getmp_rootdir(), 'lib', 'python', 'mod_python')},
      scripts=scripts,
      data_files=data_files,
      ext_modules=ext_modules)

# makes emacs go into python mode
### Local Variables:
### mode:python
### End:
