#############################################################################
## Copyright (c) 2009-2011 Ben van Klinken. All rights reserved.
## Distributable under the terms of either the Apache License (Version 2.0)
## or the GNU Lesser General Public License.
#############################################################################

import sys
import os
from copy import copy
import Options
import TaskGen
from Configure import conf
from TaskGen import feature, after
#import Task, ccroot

APPNAME='Lucene++'
VERSION='3.0.2'

top = '../../'
out = 'bin'

source_patterns = '**/*.(c|cpp)'

lucene_source_dirs = [
    top + 'src/core/analysis',
    top + 'src/core/document',
    top + 'src/core/index',
    top + 'src/core/queryparser',
    top + 'src/core/search',
    top + 'src/core/store',
    top + 'src/core/util'
]

boost_defines = [
  'BOOST_BUILD_THREAD_DLL',
  'BOOST_BUILD_FILESYSTEM_DLL',
  'BOOST_BUILD_REGEX_DLL',
  'BOOST_BUILD_DATE_TIME_DLL',
  'BOOST_BUILD_IOSTREAMS_DLL',
]
boost_sources_dirs = [
  'libs/thread/src',
  'libs/filesystem/src',
  'libs/regex/src',
  'libs/date_time/src',
  'libs/iostreams/src',
  'libs/system/src'
]
      
lucene_contrib_source_dirs = [
    top + 'src/contrib'
]

lucene_include_dirs = [
    top + 'include',
    top + 'src/core/include',
    top + 'src/contrib/include'
]

tester_source_dirs = [
    top + 'src/test'
]

tester_include_dirs = [
    top + 'include',
    top + 'src/core/include',
    top + 'src/contrib/include',
    top + 'src/test/include'
]


def options(opt):
    opt.tool_options("boost")
    opt.tool_options('compiler_cxx')
    opt.tool_options('clang', tooldir = 'build')
    opt.add_option(
        '--debug', 
        default = False,
        action = "store_true",
        help ='debug build no optimization, etc...', 
        dest = 'debug')
    
    opt.add_option(
        '--static', 
        default = False,
        action = "store_true",
        help ='fully static build', 
        dest = 'static')
        
    opt.add_option(
        '--boost', 
        default = 'boost_1_42_0',
        action = "store",
        help ='boost path', 
        dest = 'BOOST_HOME')


def configure(conf):
    conf.env['INCLUDES_BOOST'] = Options.options.BOOST_HOME
    
    conf.check_tool('g++')
    conf.check_tool('gcc')
    #now try with overridden clang...
    conf.check_tool('clang', 'build')
    conf.check_cc(lib = 'pthread', mandatory = True)
    conf.check(header_name='bzlib.h', mandatory = True)
    conf.env['LINKFLAGS_cshlib'] = ''
    conf.env['LINKFLAGS_cxxshlib'] = ''
    
    conf.check_tool('boost')
    conf.check_tool('clang', 'build')
    conf.check_boost(
        #static = 'onlystatic',
        lib = ['filesystem', 'thread', 'regex', 'system', 'date_time', 'iostreams', 'unit_test_framework']
    )
    
    if conf.env['HAVE_LLVM'] == False:
      raise Exception("No clang found")
    #if conf.path.find_dir(conf.env['INCLUDES_BOOST'] + "/libs") == None:
    #  raise Exception(conf.env['INCLUDES_BOOST'] + " does not have the libs directory or is not within the source path (" + top + ") - check that the path is correctly and points to a source distribution")
    #if conf.path.find_dir(conf.env['INCLUDES_BOOST'] + "/boost") != None:
    #  raise Exception("Please remove the boost includes path, it causes problems for some unknown reason")

def build(bld):
    target_type = 'cxxstlib'
    debug_define = '_DEBUG' if Options.options.debug else 'NDEBUG'
    compile_flags = ['-emit-llvm']
    if Options.options.debug:
         compile_flags = compile_flags + ['-O0', '-g', ] 
    else:
         compile_flags = compile_flags + ['-O3']
    
    dll_link_flags = ['-link-as-library']
    app_link_flags = ['-native', 
                      'scripts/llvm/liblucene++.a',
                      '-L/usr/lib/gcc/x86_64-linux-gnu/4.5/',
                      '-lsupc++', '-lstdc++', 
                      '-lpthread', '-lm', '-lc'
    ]
    #                        'scripts/llvm/liblucene_boost.a',  
    #                        
    #                        

    ###############
    #libraries...
    ###############
    
    lucene_sources = []
    for source_dir in lucene_source_dirs:
        source_dir = bld.path.find_dir(source_dir)
        lucene_sources.extend(source_dir.ant_glob(source_patterns))
    bld(
        name = 'lucene++',
        features = ['cxx', 'c'] + [target_type],
        source = [source.relpath_gen(bld.path) for source in lucene_sources],
        target = 'lucene++',
        includes = lucene_include_dirs + [bld.env["INCLUDES_BOOST"]],
        cflags = compile_flags,
        cxxflags = compile_flags,
        linkflags = dll_link_flags,
        defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define],
        uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD'
        )
    
    lucene_contrib_sources = []
    for source_dir in lucene_contrib_source_dirs:
        source_dir = bld.path.find_dir(source_dir)
        lucene_contrib_sources.extend(source_dir.ant_glob(source_patterns))
    bld(
        name = 'lucene_contrib',
        features = ['cxx', 'c'] + [target_type],
        source = [source.relpath_gen(bld.path) for source in lucene_contrib_sources],
        target = 'lucene_contrib',
        includes = lucene_include_dirs + [bld.env["INCLUDES_BOOST"]],
        cflags = compile_flags,
        cxxflags = compile_flags,
        linkflags = dll_link_flags,
        defines = ['LPP_BUILDING_LIB', 'LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define],
        )
    
    
    #lucene_boost_sources = []
    #for source_dir in boost_sources_dirs:
    #    if not bld.path.find_dir(bld.env["INCLUDES_BOOST"] + "/" + source_dir):
    #      raise Exception(source_dir + " was not found or is not inside the lucene path")
    #    source_dir = bld.path.find_dir(bld.env["INCLUDES_BOOST"] + "/" + source_dir)
    #    lucene_boost_sources.extend(source_dir.ant_glob(source_patterns, excl='win32'))
    #bld(
    #    name = 'lucene_boost',
    #    features = ['cxx', 'c'] + [target_type],
    #    source = [source.relpath_gen(bld.path) for source in lucene_boost_sources],
    #    target = 'lucene_boost',
    #    includes = bld.env["INCLUDES_BOOST"],
    #    cflags = compile_flags,
    #    cxxflags = compile_flags,
    #    linkflags = dll_link_flags,
    #    defines = [debug_define] + boost_defines,
    #)
    
    ##########
    # applications
    ##########

    tester_sources = []
    for source_dir in tester_source_dirs:
        source_dir = bld.path.find_dir(source_dir)
        tester_sources.extend(source_dir.ant_glob(source_patterns))
    
    #bld(
    #    name = 'lucene_tester',
    #    features = ['cxx', 'c', 'cprogram'],
    #    #source = [source.relpath_gen(bld.path) for source in tester_sources],
    #    target = 'lucene_tester',
    #    includes = tester_include_dirs + [bld.env["INCLUDES_BOOST"]],
    #    cflags = compile_flags,
    #    cxxflags = compile_flags,
    #    linkflags = app_link_flags,
    #    defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + ['LPP_EXPOSE_INTERNAL'] + [debug_define],
    #    uselib = 'PTHREAD',
    #    use = 'lucene++ lucene_contrib'
    #    )
    
    bld(
        name = 'deletefiles',
        features = ['cxx', 'c', 'cprogram'],
        source = bld.path.find_resource(top + 'src/demo/deletefiles/main.cpp').relpath_gen(bld.path),
        target = 'deletefiles',
        includes = [top + 'include'] + [bld.env["INCLUDES_BOOST"]],
        cflags = compile_flags,
        cxxflags = compile_flags,
        linkflags = app_link_flags,
        defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define],
        uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD',
        uselib_local = 'lucene++'
        )

    bld(
        name = 'indexfiles',
        features = ['cxx', 'c', 'cprogram'],
        source = bld.path.find_resource(top + 'src/demo/indexfiles/main.cpp').relpath_gen(bld.path),
        target = 'indexfiles',
        includes = [top + 'include'] + [bld.env["INCLUDES_BOOST"]],
        cflags = compile_flags,
        cxxflags = compile_flags,
        linkflags = app_link_flags,
        defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define],
        uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD',
        uselib_local = 'lucene++'
        )
        
    bld(
        name = 'searchfiles',
        features = ['cxx', 'c', 'cprogram'],
        source = bld.path.find_resource(top + 'src/demo/searchfiles/main.cpp').relpath_gen(bld.path),
        target = 'searchfiles',
        includes = [top + 'include'] + [bld.env["INCLUDES_BOOST"]],
        cflags = compile_flags,
        cxxflags = compile_flags,
        linkflags = app_link_flags,
        defines = ['LPP_HAVE_GXXCLASSVISIBILITY'] + [debug_define],
        uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX BOOST_SYSTEM BOOST_DATE_TIME BOOST_IOSTREAMS PTHREAD',
        uselib_local = 'lucene++'
        )
        
        
        #Todo:
        #llvm-ld -native *.so target.bc -o ntv -lsupc++ -lstdc++ -L/usr/lib/llvm-2.8/gcc-4.2/lib64 -lpthread

