# -*- python -*-
from waflib import Options

def options(opt):
  opt.add_option('--regexp-library',
                 default='oniguruma',
                 help='use regexp library: oniguruma (default), re2 or none')
  opt.add_option('--enable-fvconverter-dynamic',
                 action='store_true', default=True,
                 help='enabling fv_converter dynamic method')

def configure(conf):
  regexp_lib = Options.options.regexp_library
  if regexp_lib == 're2':
    conf.check_cxx(lib = 're2', define_name = 'HAVE_RE2',
                   errmsg = 'not found')
  elif regexp_lib == 'oniguruma':
    conf.check_cxx(lib = 'onig', define_name = 'HAVE_ONIGURUMA',
                   errmsg = 'not found')
  elif regexp_lib == 'none':
    pass
  else:
    conf.fatal('unsupported regexp library specified: ' + regexp_lib)

  if Options.options.enable_fvconverter_dynamic:
    conf.check_cxx(lib='dl', define_name='HAVE_DL', errmsg = 'not found', mandatory = False)
    libpat = conf.env.cxxshlib_PATTERN
    conf.define('LIBSPLITTER_SAMPLE', './' + libpat % 'splitter_sample')
    conf.define('LIBSPLITTER_NULL', './' + libpat % 'splitter_null')
    conf.define('LIBFILTER_SAMPLE', './' + libpat % 'filter_sample')
    conf.define('LIBNUM_FEATURE_SAMPLE', './' + libpat % 'num_feature_sample')
    conf.define('LIBNUM_FILTER_SAMPLE', './' + libpat % 'num_filter_sample')
    conf.define('LIBBINARY_FEATURE_SAMPLE', './' + libpat % 'binary_feature_sample')

def make_test(bld, use, src):
  bld.program(
    features = 'gtest',
    source = src,
    target = src[0:src.rindex('.')],
    use = use,
    cxxflags = ['-DGTEST_HAS_POSIX_RE=0']
    )

def make_tests(bld, use, srcs):
  for src in srcs:
    make_test(bld, use, src)


def build(bld):
  source = [
    'util.cpp',
    'json_converter.cpp',
    'msgpack_converter.cpp',
    'datum_to_fv_converter.cpp',
    'space_splitter.cpp',
    'character_ngram.cpp',
    'without_split.cpp',
    'key_matcher_factory.cpp',
    'string_feature_factory.cpp',
    'num_feature_factory.cpp',
    'binary_feature_factory.cpp',
    'combination_feature_factory.cpp',
    'converter_config.cpp',
    'libsvm_converter.cpp',
    'string_filter_factory.cpp',
    'num_filter_factory.cpp',
    'revert.cpp',
    'weight_manager.cpp',
    'keyword_weights.cpp',
    'feature_hasher.cpp',
    'word_splitter.cpp',
    'char_splitter.cpp',
    ]
  headers = [
      'binary_feature_factory.hpp',
      'binary_feature.hpp',
      'character_ngram.hpp',
      'combination_feature_factory.hpp',
      'combination_feature.hpp',
      'combination_feature_impl.hpp',
      'converter_config.hpp',
      'counter.hpp',
      'datum.hpp',
      'datum_to_fv_converter.hpp',
      'exact_match.hpp',
      'exception.hpp',
      'except_match.hpp',
      'factory.hpp',
      'feature_hasher.hpp',
      'json_converter.hpp',
      'key_matcher_factory.hpp',
      'key_matcher.hpp',
      'keyword_weights.hpp',
      'libsvm_converter.hpp',
      'match_all.hpp',
      'mixable_weight_manager.hpp',
      'msgpack_converter.hpp',
      'num_feature_factory.hpp',
      'num_feature.hpp',
      'num_feature_impl.hpp',
      'num_filter_factory.hpp',
      'num_filter.hpp',
      'num_filter_impl.hpp',
      'prefix_match.hpp',
      'revert.hpp',
      'space_splitter.hpp',
      'string_feature_factory.hpp',
      'string_feature.hpp',
      'string_filter_factory.hpp',
      'string_filter.hpp',
      'suffix_match.hpp',
      'type.hpp',
      'util.hpp',
      'weight_manager.hpp',
      'without_split.hpp',
      'word_splitter.hpp',
      'char_splitter.hpp',
  ]
  test_source = [
      'json_converter_test.cpp',
      'msgpack_converter_test.cpp',
      'datum_to_fv_converter_test.cpp',
      'space_splitter_test.cpp',
      'character_ngram_test.cpp',
      'key_matcher_test.cpp',
      'key_matcher_factory_test.cpp',
      'string_feature_factory_test.cpp',
      'num_feature_factory_test.cpp',
      'combination_feature_factory_test.cpp',
      'converter_config_test.cpp',
      'libsvm_converter_test.cpp',
      'string_filter_factory_test.cpp',
      'num_filter_impl_test.cpp',
      'num_filter_factory_test.cpp',
      'counter_test.cpp',
      'revert_test.cpp',
      'weight_manager_test.cpp',
      'keyword_weights_test.cpp',
      'feature_hasher_test.cpp',
      'except_match_test.cpp',
      'mixable_weight_manager_test.cpp',
      'char_splitter_test.cpp',
  ]

  # Note: these headers are intentionally not installed.
  regex_headers = [
    'regexp_filter.hpp',
    'regexp_match.hpp',
    'regexp_splitter.hpp',
    'onig_filter.hpp',
    'onig_match.hpp',
    'onig_splitter.hpp',
    're2_filter.hpp',
    're2_match.hpp',
    're2_splitter.hpp',
  ]
  regex_test_source = [
      'regexp_match_test.cpp',
      'regexp_filter_test.cpp',
      'regexp_splitter_test.cpp',
  ]

  use = ['jubatus_util', 'MSGPACK']

  if 'HAVE_RE2' in bld.env.define_key:
    source += ['re2_match.cpp', 're2_filter.cpp', 're2_splitter.cpp' ]
    test_source += regex_test_source
    use += ['RE2']
  elif 'HAVE_ONIGURUMA' in bld.env.define_key:
    source += ['onig_match.cpp', 'onig_filter.cpp', 'onig_splitter.cpp']
    test_source += regex_test_source
    use += ['ONIG']

  if Options.options.enable_fvconverter_dynamic:
    source += [
      'so_factory.cpp',
      'dynamic_loader.cpp',
      'dynamic_string_feature.cpp',
      'dynamic_num_feature.cpp',
      'dynamic_binary_feature.cpp',
      'dynamic_string_filter.cpp',
      'dynamic_num_filter.cpp',
      'dynamic_combination_feature.cpp',
    ]
    headers += [
      'so_factory.hpp',
    ]
    test_source += [
      'dynamic_loader_test.cpp',
      'dynamic_string_feature_test.cpp',
      'dynamic_num_feature_test.cpp',
      'dynamic_binary_feature_test.cpp',
      'dynamic_string_filter_test.cpp',
      'dynamic_num_filter_test.cpp',
      'so_factory_test.cpp',
    ]
    use += ['DL']
    # Note: If you specify `vnum` for shared libraries
    #       whose install_path = None, waf cause an error
    #       when doing ./waf install.
    bld.shlib(
      source = 'test_splitter.cpp',
      target = 'splitter_sample',
      install_path = None,
      name = 'splitter_sample',
      use = 'jubatus_core'
    )

    bld.shlib(
      source = 'test_splitter_null.cpp',
      target = 'splitter_null',
      install_path = None,
      name = 'splitter_null',
      use = 'jubatus_core'
    )

    bld.shlib(
      source = 'test_num_feature.cpp',
      target = 'num_feature_sample',
      install_path = None,
      name = 'num_feature_sample',
      use = 'jubatus_core'
    )

    bld.shlib(
      source = 'test_num_filter.cpp',
      target = 'num_filter_sample',
      install_path = None,
      name = 'num_filter_sample',
      use = 'jubatus_core'
    )

    bld.shlib(
      source = 'test_binary_feature.cpp',
      target = 'binary_feature_sample',
      install_path = None,
      name = 'binary_feature_sample',
      use = 'jubatus_core'
    )

    bld.shlib(
      source = 'test_string_filter.cpp',
      target = 'filter_sample',
      install_path = None,
      name = 'filter_sample',
      use = 'jubatus_core'
    )

  bld.core_sources.extend(bld.add_prefix(source))
  bld.core_headers.extend(bld.add_prefix(headers))
  bld.core_use.extend(use)

  n = bld.path.get_bld().make_node('test_input')
  n.mkdir()
  bld(rule = 'cp ${SRC} ${TGT}',
      source = bld.path.ant_glob('test_input/*'),
      target = n)

  test_use = ['jubatus_util', 'jubatus_core']

  make_tests(bld, test_use, test_source)
