#!/usr/bin/env python
# Copyright (C) 2019 Sylvain Marsat, John G. Baker
#

"""
setup.py file for lisabeta package
"""

from __future__ import print_function

import sys, os, subprocess, shutil

from distutils.errors import DistutilsError
from distutils.command.clean import clean as _clean

from setuptools.command.install import install as _install
from setuptools import Extension, setup, Command
from setuptools.command.build_ext import build_ext as _build_ext
from setuptools import find_packages

from Cython.Build import cythonize

import numpy

# Classifiers for distribution of package
classifiers = [
    'Programming Language :: Python',
    'Programming Language :: Cython',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.5',
    'Intended Audience :: Science/Research',
    'Natural Language :: English',
    'Topic :: Scientific/Engineering',
    'Topic :: Scientific/Engineering :: Astronomy',
    'Topic :: Scientific/Engineering :: Physics',
    'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
]

requires = []
setup_requires = ['numpy',]
install_requires = setup_requires + [
                      'cython',
                      'scipy',
                      'matplotlib',
                      'h5py',
                      'astropy'
                      ]

# def find_files(dirname, relpath=None):
#     def find_paths(dirname):
#         items = []
#         for fname in os.listdir(dirname):
#             path = os.path.join(dirname, fname)
#             if os.path.isdir(path):
#                 items += find_paths(path)
#             elif not path.endswith(".py") and not path.endswith(".pyc"):
#                 items.append(path)
#         return items
#     items = find_paths(dirname)
#     if relpath is None:
#         relpath = dirname
#     return [os.path.relpath(path, relpath) for path in items]

# class cbuild_ext(_build_ext):
#     def run(self):
#         import pkg_resources
#
#         # At this point we can be sure pip has already installed numpy
#         numpy_incl = pkg_resources.resource_filename('numpy', 'core/include')
#
#         for ext in self.extensions:
#             if (hasattr(ext, 'include_dirs') and
#                     numpy_incl not in ext.include_dirs):
#                 ext.include_dirs.append(numpy_incl)
#
#         _build_ext.run(self)

# # write versioning info
# def get_version_info():
#     """Get VCS info and write version info to version.py
#     """
#     from pycbc import _version_helper
#
#     class vdummy(object):
#         def __getattr__(self, attr):
#             return ''
#
#     # If this is a pycbc git repo always populate version information using GIT
#     try:
#         vinfo = _version_helper.generate_git_version_info()
#     except:
#         vinfo = vdummy()
#         vinfo.version = '1.13.dev7'
#         vinfo.release = 'False'
#
#     with open('pycbc/version.py', 'w') as f:
#         f.write("# coding: utf-8\n")
#         f.write("# Generated by setup.py for PyCBC on %s.\n\n"
#                 % vinfo.build_date)
#
#         # print general info
#         f.write('version = \'%s\'\n' % vinfo.version)
#         f.write('date = \'%s\'\n' % vinfo.date)
#         f.write('release = %s\n' % vinfo.release)
#         f.write('last_release = \'%s\'\n' % vinfo.last_release)
#
#         # print git info
#         f.write('\ngit_hash = \'%s\'\n' % vinfo.hash)
#         f.write('git_branch = \'%s\'\n' % vinfo.branch)
#         f.write('git_tag = \'%s\'\n' % vinfo.tag)
#         f.write('git_author = \'%s\'\n' % vinfo.author)
#         f.write('git_committer = \'%s\'\n' % vinfo.committer)
#         f.write('git_status = \'%s\'\n' % vinfo.status)
#         f.write('git_builder = \'%s\'\n' % vinfo.builder)
#         f.write('git_build_date = \'%s\'\n' % vinfo.build_date)
#         f.write('git_verbose_msg = """Version: %s\n'
#                 'Branch: %s\n'
#                 'Tag: %s\n'
#                 'Id: %s\n'
#                 'Builder: %s\n'
#                 'Build date: %s\n'
#                 'Repository status is %s"""\n' %(
#                                                vinfo.version,
#                                                vinfo.branch,
#                                                vinfo.tag,
#                                                vinfo.hash,
#                                                vinfo.builder,
#                                                vinfo.build_date,
#                                                vinfo.status))
#         f.write('from pycbc._version import *\n')
#         version = vinfo.version
#
#     from pycbc import version
#     version = version.version
#     return version

# class build_docs(Command):
#     user_options = []
#     description = "Build the documentation pages"
#     def initialize_options(self):
#         pass
#     def finalize_options(self):
#         pass
#     def run(self):
#         subprocess.check_call("cd docs; cp Makefile.std Makefile; cp conf_std.py conf.py; sphinx-apidoc "
#                               " -o ./ -f -A 'PyCBC dev team' -V '0.1' ../pycbc && make html",
#                             stderr=subprocess.STDOUT, shell=True)

# class build_gh_pages(Command):
#     user_options = []
#     description = "Build the documentation pages for GitHub"
#     def initialize_options(self):
#         pass
#     def finalize_options(self):
#         pass
#     def run(self):
#         subprocess.check_call("mkdir -p _gh-pages/latest && touch _gh-pages/.nojekyll && "
#                               "cd docs; cp Makefile.gh_pages Makefile; cp conf_std.py conf.py; sphinx-apidoc "
#                               " -o ./ -f -A 'PyCBC dev team' -V '0.1' ../pycbc && make html",
#                             stderr=subprocess.STDOUT, shell=True)

# cmdclass = { 'build_docs' : build_docs,
#              'build_gh_pages' : build_gh_pages,
#              'clean' : clean,
#              'build_ext':cbuild_ext
#             }

#extras_require = {'cuda': ['pycuda>=2015.1', 'scikit-cuda']}

# do the actual work of building the package
#VERSION = get_version_info()

argv_replace = []
constants = ''
gsl_prefix = '/usr'
force_recompile=False
for arg in sys.argv:
    if arg.startswith('--with-gsl='):
        gsl_prefix = arg.split('=', 1)[1]
    elif arg.startswith('--with-constants='):
        constants = arg.split('=', 1)[1]
    elif arg=='--force':
        force_recompile = True
    else:
        argv_replace.append(arg)
sys.argv = argv_replace

# If using LDC constants, define a macro to pass to the compiler
if constants=='' or constants=='LAL':
    Dconstants = '-DNOP'
elif constants=='LDC':
    Dconstants = '-DLDCCONSTANTS'
elif constants=='LISA':
    Dconstants = '-DLISACONSTANTS'

#Compiler
#os.environ["CC"] = "/opt/local/bin/gcc-mp-8"
#os.environ["CXX"] = "/opt/local/bin/g++-mp-8"

# Extensions
lib_gsl_dir = gsl_prefix+"/lib"
include_gsl_dir = gsl_prefix+"/include"
# Note: we use only one list of include dirs with everything needed in it
#extra_compile_args = [Dconstants]
extra_link_args= []
#if(0):
    #compiler for memory debugging:
    #Note: to get this to run I need to execute (for macports python 3.7):
    # DYLD_INSERT_LIBRARIES=/Applications/Xcode10.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/10.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib /opt/local/Library/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python
    # extra_compile_args += [ "-fsanitize=address","-fno-omit-frame-pointer", "-Wno-format-security"]
    # extra_link_args += ["-fsanitize=address"]
extra_compile_args = ['-std=c99']
all_include_dirs = [numpy.get_include(), include_gsl_dir, "lisabeta/",
                    "lisabeta/struct", "lisabeta/tools", "lisabeta/lisa"]
all_libraries = ["gsl", "gslcblas"]
all_library_dirs = [lib_gsl_dir]
def func_extension(ext, sources=[]):
    return Extension(ext,
              sources=sources,
              include_dirs=all_include_dirs,
              language="c",
              extra_compile_args=extra_compile_args,
              #extra_link_args=extra_link_args,
              libraries=all_libraries,
              library_dirs=all_library_dirs)
extensions = [
    func_extension("lisabeta.pyconstants",
      sources=["lisabeta/pyconstants.pyx"]),
    func_extension("lisabeta.struct.pystruct",
      sources=["lisabeta/struct/pystruct.pyx",
      "lisabeta/struct/struct.c"]),
    func_extension("lisabeta.tools.pytools",
      sources=["lisabeta/tools/pytools.pyx",
      "lisabeta/tools/tools.c",
      "lisabeta/struct/struct.c",
      "lisabeta/tools/spline.c"]),
    func_extension("lisabeta.tools.pyspline",
      sources=["lisabeta/tools/pyspline.pyx",
      "lisabeta/tools/spline.c",
      "lisabeta/struct/struct.c",
      "lisabeta/tools/tools.c"]),
    func_extension("lisabeta.tools.pyoverlap",
      sources=["lisabeta/tools/pyoverlap.pyx",
      "lisabeta/tools/spline.c",
      "lisabeta/struct/struct.c",
      "lisabeta/tools/tools.c",
      "lisabeta/tools/fresnel.c",
      "lisabeta/tools/overlap.c"]),
    func_extension("lisabeta.lisa.pyresponse",
      sources=["lisabeta/lisa/pyresponse.pyx",
      "lisabeta/lisa/LISAresponse.c",
      "lisabeta/lisa/LISAgeometry.c",
      "lisabeta/tools/spline.c",
      "lisabeta/struct/struct.c",
      "lisabeta/tools/tools.c"]),
    func_extension("lisabeta.lisa.pyLISAnoise",
      sources=["lisabeta/lisa/pyLISAnoise.pyx",
      "lisabeta/lisa/LISAnoise.c",
      "lisabeta/lisa/LISAgeometry.c",
      "lisabeta/struct/struct.c"]),
    func_extension("lisabeta.waveforms.bbh.pyIMRPhenomD",
      sources=["lisabeta/waveforms/bbh/pyIMRPhenomD.pyx",
      "lisabeta/waveforms/bbh/IMRPhenomD.c",
      "lisabeta/waveforms/bbh/IMRPhenomD_internals.c",
      "lisabeta/waveforms/bbh/IMRPhenomUtils.c",
      "lisabeta/waveforms/bbh/IMRPhenomInternalUtils.c",
      "lisabeta/struct/struct.c"]),
    func_extension("lisabeta.waveforms.bbh.pyIMRPhenomHM",
      sources=["lisabeta/waveforms/bbh/pyIMRPhenomHM.pyx",
      "lisabeta/waveforms/bbh/IMRPhenomHM.c",
      "lisabeta/waveforms/bbh/IMRPhenomD_internals.c",
      "lisabeta/waveforms/bbh/IMRPhenomUtils.c",
      "lisabeta/waveforms/bbh/IMRPhenomInternalUtils.c",
      "lisabeta/waveforms/bbh/RingdownCW.c",
      "lisabeta/struct/struct.c"]),
    func_extension("lisabeta.waveforms.bbh.pyEOBNRv2HMROM",
      sources=["lisabeta/waveforms/bbh/pyEOBNRv2HMROM.pyx",
      "lisabeta/waveforms/bbh/EOBNRv2HMROM.c",
      "lisabeta/waveforms/bbh/EOBNRv2HMROMstruct.c",
      "lisabeta/struct/struct.c"])
]
ext_modules = cythonize(extensions,force=force_recompile)


setup(
    name = 'lisabeta',
    version = '0.1.0',
    description = 'Library to analyze gravitational-wave signals in LISA and LIGO-type detectors.',
    #long_description = open('descr.rst').read(),
    author = 'Sylvain Marsat and John Baker and ...',
    author_email = 'marsat@apc.in2p3.fr',
    #url = 'http://www.pycbc.org/',
    #download_url = 'https://github.com/gwastro/pycbc/tarball/v%s' % VERSION,
    keywords = ['lisa', 'ligo', 'physics', 'gravity', 'signal processing', 'gravitational waves'],
    #cmdclass = cmdclass,
    setup_requires = setup_requires,
    #extras_require = extras_require,
    install_requires = install_requires,
    #scripts  = find_files('bin', relpath='./') + ['tools/einsteinathome/pycbc_build_eah.sh'],
    packages = find_packages(),
    #package_data = {'pycbc.workflow': find_files('pycbc/workflow'),
    #                'pycbc.results': find_files('pycbc/results'),
    #                'pycbc.tmpltbank': find_files('pycbc/tmpltbank')},
    ext_modules = ext_modules,
    classifiers = classifiers
)
