#!/usr/bin/env python

"""
PETSc for Python
================

Python bindings for PETSc libraries.
"""


## try:
##     import setuptools
## except ImportError:
##     pass


# -----------------------------------------------------------------------------
# Metadata
# -----------------------------------------------------------------------------

from conf.metadata import metadata

def version():
    import os, re
    data = open(os.path.join('src', '__init__.py')).read()
    m = re.search(r"__version__\s*=\s*'(.*)'", data)
    return m.groups()[0]

name     = 'petsc4py'
version  = version()

url      = 'http://%(name)s.googlecode.com/' % vars()
download = url + 'files/%(name)s-%(version)s.tar.gz' % vars()

descr    = __doc__.strip().split('\n'); del descr[1:3]
devstat  = ['Development Status :: 3 - Alpha']
keywords = ['PETSc', 'MPI']

metadata['name'] = name
metadata['version'] = version
metadata['description'] = descr.pop(0)
metadata['long_description'] = '\n'.join(descr)
metadata['keywords'] += keywords
metadata['classifiers'] += devstat
metadata['url'] = url
metadata['download_url'] = download

metadata['provides'] = ['petsc4py']
metadata['requires'] = ['numpy']

# -----------------------------------------------------------------------------
# Extension modules
# -----------------------------------------------------------------------------

def get_ext_modules(Extension):
    from os   import walk, path
    from glob import glob
    depends = []
    for pth, dirs, files in walk('src'):
        depends += glob(path.join(pth, '*.h'))
    for pth, dirs, files in walk(path.join('src', 'source')):
        depends += glob(path.join(pth, '*.h'))
        depends += glob(path.join(pth, '*.c'))
    try:
        import numpy
        numpy_includes = [numpy.get_include()]
    except ImportError:
        numpy_includes = []
    return [Extension('petsc4py.lib.PETSc',
                      sources=['src/PETSc.c',
                               'src/source/libpetsc4py.c',
                               ],
                      include_dirs=['src/include',
                                    'src/source',
                                    ] + numpy_includes,
                      depends=depends)]

# -----------------------------------------------------------------------------
# Setup
# -----------------------------------------------------------------------------

from conf.petscconf import setup, Extension
from conf.petscconf import config, build, build_ext

def run_setup():
    setup(packages     = ['petsc4py',
                          'petsc4py.lib',],
          package_dir  = {'petsc4py'     : 'src',
                          'petsc4py.lib' : 'src/lib'},
          package_data = {'petsc4py'     : ['include/petsc4py/*.h',
                                            'include/petsc4py/*.i',
                                            'include/petsc4py/*.pxd',
                                            'include/petsc4py/*.pxi',
                                            'include/petsc4py/*.pyx',],
                          'petsc4py.lib' : ['petsc.cfg'],},
          ext_modules  = get_ext_modules(Extension),
          cmdclass     = {'config'     : config,
                          'build'      : build,
                          'build_ext'  : build_ext},
          **metadata)

def run_cython(*C_SOURCE):
    import sys, os
    if os.path.exists(os.path.join(*C_SOURCE)): return
    if "install" not in sys.argv: return
    warn = lambda msg='': sys.stderr.write(msg+'\n')
    warn("*"*80)
    warn()
    warn(" Attempting to generate C source files with Cython!!")
    warn()
    warn("*"*80)
    try:
        import conf.cythonize
        conf.cythonize.run('petsc4py.PETSc.pyx', wdir='src')
    except ImportError:
        warn("*"*80)
        warn()
        warn(" Download and install Cython <http://www.cython.org>")
        warn(" and next execute in your shell:")
        warn()
        warn("   $ python ./conf/cythonize.py")
        warn()
        warn("*"*80)
        raise
    except:
        warn("*"*80)
        warn()
        warn(" Unable to generate C source files with Cython!!")
        warn()
        warn("*"*80)
        raise

def install_petsc():
    import os,sys
    if 'PETSC_DIR' in os.environ: return
    if "install" not in sys.argv: return
    warn = lambda msg='': sys.stderr.write(msg+'\n')
    warn("*"*80)
    warn()
    warn(" PETSC_DIR is not set in your environment, downloading and installing PETSc!!")
    warn()
    warn("*"*80)
    import urllib
#    urllib.urlretrieve('http://ftp.mcs.anl.gov/pub/petsc/petsc-dev.tar.gz', 'petsc.tar.gz')
    import tarfile
    f = tarfile.open('petsc.tar.gz')
#    f.extractall()
    f.close()
    cwd = os.getcwd()
    os.environ['PETSC_DIR'] = os.path.abspath(os.path.join(cwd,'petsc-dev'))
    os.chdir(os.environ['PETSC_DIR'])
    sys.path.insert(0,os.path.join(os.environ['PETSC_DIR'],'config'))
    import configure
    configure.petsc_configure([])
    os.chdir(cwd)
    sys.exit(0)

    
if __name__ == '__main__':
    run_cython('src', 'petsc4py.PETSc.c')
    install_petsc()
    try:
        run_setup()
    except:
        raise

# -----------------------------------------------------------------------------
