# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
VERSION='0.3~dev0'
NAME="ndn-cpp-dev"

from waflib import Build, Logs, Utils, Task, TaskGen, Configure

def options(opt):
    opt.load('compiler_c compiler_cxx gnu_dirs c_osx')
    opt.load('boost doxygen openssl cryptopp', tooldir=['.waf-tools'])

    opt = opt.add_option_group('NDN-CPP Options')

    opt.add_option('--debug',action='store_true',default=False,dest='debug',help='''debugging mode''')
    
    opt.add_option('--with-tests', action='store_true',default=False,dest='with_tests',
                   help='''build unit tests''')
    opt.add_option('--with-log4cxx', action='store_true',default=False,dest='log4cxx',
                   help='''Compile with log4cxx logging support''')

    opt.add_option('--with-c++11', action='store_true', default=False, dest='use_cxx11',
                   help='''Use C++11 features, even if available in the compiler''')
    opt.add_option('--without-system-boost', action='store_false', default=True, dest='use_system_boost',
                   help='''Use system's boost libraries''')


def configure(conf):
    conf.load("compiler_c compiler_cxx boost gnu_dirs c_osx openssl cryptopp")
    try:
        conf.load("doxygen")
    except:
        pass

    if conf.options.with_tests:
        conf.env['WITH_TESTS'] = True

    # Optional functions
    for func in ['memcmp', 'memcpy', 'memset']:
        conf.check(function_name=func, header_name='string.h', mandatory=False)

    # Mandatory functions
    for func in ['strchr', 'sscanf']:
        conf.check(function_name=func, header_name=['string.h', 'stdio.h'])

    # Mandatory headers
    for header in ['time.h', 'sys/time.h']:
        conf.check(header_name=header)

    conf.check(function_name='gettimeofday', header_name=['time.h', 'sys/time.h'])

    conf.check_openssl()

    if conf.options.debug:
        conf.define ('_DEBUG', 1)
        flags = ['-O0',
                 '-Wall',
                 # '-Werror',
                 '-Wno-unused-variable',
                 '-g3',
                 '-Wno-unused-private-field', # only clang supports
                 '-fcolor-diagnostics',       # only clang supports
                 '-Qunused-arguments',        # only clang supports
                 '-Wno-tautological-compare', # suppress warnings from CryptoPP
                 '-Wno-unused-function',      # another annoying warning from CryptoPP

                 '-Wno-deprecated-declarations',
                 ]

        conf.add_supported_cxxflags (cxxflags = flags)
    else:
        flags = ['-O3', '-g', '-Wno-tautological-compare', '-Wno-unused-function', '-Wno-deprecated-declarations']
        conf.add_supported_cxxflags (cxxflags = flags)

    if Utils.unversioned_sys_platform () == "darwin":
        conf.check_cxx(framework_name='CoreFoundation', uselib_store='OSX_COREFOUNDATION', mandatory=True)
        conf.check_cxx(framework_name='CoreServices', uselib_store='OSX_CORESERVICES', mandatory=True)
        conf.check_cxx(framework_name='Security',   uselib_store='OSX_SECURITY',   define_name='HAVE_SECURITY',
                       use="OSX_COREFOUNDATION", mandatory=True)
        conf.define('HAVE_OSX_SECURITY', 1)

    conf.define ("PACKAGE_BUGREPORT", "ndn-lib@lists.cs.ucla.edu")
    conf.define ("PACKAGE_NAME", NAME)
    conf.define ("PACKAGE_VERSION", VERSION)
    conf.define ("PACKAGE_URL", "https://github.com/named-data/ndn-cpp")

    conf.check_cfg(package='sqlite3', args=['--cflags', '--libs'], uselib_store='SQLITE3', mandatory=True)

    if conf.options.log4cxx:
        conf.check_cfg(package='liblog4cxx', args=['--cflags', '--libs'], uselib_store='LOG4CXX', mandatory=True)
        conf.define ("HAVE_LOG4CXX", 1)

    conf.check_cryptopp(path=conf.options.cryptopp_dir, mandatory=True)

    if conf.options.use_cxx11:
        conf.add_supported_cxxflags(cxxflags = ['-std=c++11', '-std=c++0x'])

        conf.check(msg='Checking for type std::shared_ptr',
                   type_name="std::shared_ptr<int>", header_name="memory", define_name='HAVE_STD_SHARED_PTR')
        conf.check(msg='Checking for type std::function',
                   type_name="std::function<void()>", header_name="functional", define_name='HAVE_STD_FUNCTION')
        conf.define('HAVE_CXX11', 1)
    else:
        if conf.options.use_system_boost:
            USED_BOOST_LIBS = 'system filesystem iostreams'
            if conf.env['WITH_TESTS']:
                USED_BOOST_LIBS += " unit_test_framework"

            conf.check_boost(lib=USED_BOOST_LIBS)

            boost_version = conf.env.BOOST_VERSION.split('_')
            if int(boost_version[0]) > 1 or (int(boost_version[0]) == 1 and int(boost_version[1]) >= 46):
                conf.env['USE_SYSTEM_BOOST'] = True
                conf.define('USE_SYSTEM_BOOST', 1)

    conf.write_config_header('include/ndn-cpp-dev/ndn-cpp-config.h', define_prefix='NDN_CPP_')

def build (bld):
    libndn_cpp = bld (
        target="lib-objects",
        name = "lib-objects",
        features=['cxx'],
        source = bld.path.ant_glob(['src/**/*.cpp',
                                    'new/**/*.cpp']),
        use = 'BOOST OPENSSL LOG4CXX CRYPTOPP SQLITE3',
        includes = "include",
        export_includes = "include",
        )

    if Utils.unversioned_sys_platform () == "darwin":
        libndn_cpp.mac_app = True
        libndn_cpp.use += " OSX_COREFOUNDATION OSX_SECURITY"

    shlib = bld(features = 'cxx cxxshlib',
                vnum = "0.3.0",
                target = "ndn-cpp-dev",
                use = "lib-objects",
                name = "ndn-cpp-dev-shlib",
                )

    stlib = bld(features = 'cxx cxxstlib',
                target = "ndn-cpp-dev",
                use = "lib-objects",
                name = "ndn-cpp-dev-stlib",
                )
        
    bld (features = "subst",
         source = "libndn-cpp-dev.pc.in",
         target = "libndn-cpp-dev.pc",
         install_path = "${LIBDIR}/pkgconfig",
        )
        
    # Unit tests
    if bld.env['WITH_TESTS']:
        bld.recurse('tests')

    bld.recurse("tools examples")
      
    headers = bld.path.ant_glob(['src/**/*.hpp',
                                 'src/**/*.h'])
    bld.install_files("%s/ndn-cpp" % bld.env['INCLUDEDIR'], headers, relative_trick=True, cwd=bld.path.find_node('src'))

    bld.install_files("%s/ndn-cpp" % bld.env['INCLUDEDIR'], bld.path.find_resource('include/ndn-cpp/ndn-cpp-config.h'))

    headers = bld.path.ant_glob(['include/**/*.hpp', 'include/**/*.h'])
    bld.install_files("%s" % bld.env['INCLUDEDIR'], headers, relative_trick=True, cwd=bld.path.find_node('include'))

@Configure.conf
def add_supported_cxxflags(self, cxxflags):
    """
    Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
    """
    self.start_msg('Checking allowed flags for c++ compiler')

    supportedFlags = []
    for flag in cxxflags:
        if self.check_cxx (cxxflags=[flag], mandatory=False):
            supportedFlags += [flag]

    self.end_msg (' '.join (supportedFlags))
    self.env.CXXFLAGS += supportedFlags

# doxygen docs
from waflib.Build import BuildContext
class doxy (BuildContext):
    cmd = "doxygen"
    fun = "doxygen"

def doxygen (bld):
    if not bld.env.DOXYGEN:
        bld.fatal ("ERROR: cannot build documentation (`doxygen' is not found in $PATH)")
    bld (features="doxygen",
         doxyfile='Doxyfile')

# doxygen docs
from waflib.Build import BuildContext
class sphinx (BuildContext):
    cmd = "sphinx"
    fun = "sphinx"

def sphinx (bld):
    bld.load('sphinx_build', tooldir=['waf-tools'])

    bld (features="sphinx",
         outdir = "doc/html",
         source = "doc/source/conf.py")
