##############################################################################
# BEGIN_COPYRIGHT
#
# Copyright (C) 2008-2019 SciDB, Inc.
# All Rights Reserved.
#
# SciDB is free software: you can redistribute it and/or modify
# it under the terms of the AFFERO GNU General Public License as published by
# the Free Software Foundation.
#
# SciDB is distributed "AS-IS" AND WITHOUT ANY WARRANTY OF ANY KIND,
# INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
# NON-INFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. See
# the AFFERO GNU General Public License for the complete license terms.
#
# You should have received a copy of the AFFERO GNU General Public License
# along with SciDB.  If not, see <http://www.gnu.org/licenses/agpl-3.0.html>
#
# END_COPYRIGHT
##############################################################################

add_subdirectory("ops")

flex_target(Lexer  parser/Lexer.ll  ${CMAKE_CURRENT_BINARY_DIR}/parser/Lexer.cpp)
bison_target(Parser parser/Parser.yy ${CMAKE_CURRENT_BINARY_DIR}/parser/Parser.cpp)
add_flex_bison_dependency(Lexer Parser)

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/parser)

include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/parser/)

set(query_parser_src
    parser/Node.cpp
    parser/Table.cpp
    parser/Driver.cpp
    parser/Module.cpp
    parser/Factory.cpp
    parser/Inliner.cpp
    parser/Visitor.cpp
    parser/Keywords.cpp
    parser/Unparser.cpp
    parser/Desugarer.cpp
    parser/Translator.cpp
    parser/ListMacros.cpp
    parser/ParsingContext.cpp
    parser/AstWriter.cpp
)


#
# HACKS BEGINS HERE
#

# Fixing isatty declaration in source file generated by FLEX on linux.
# Related bug: http://sourceforge.net/tracker/index.php?func=detail&aid=1984987&group_id=97492&atid=618177
#
#    Rather than this hack, adding '%option never-interactive' to Lexer.ll results in a
#    generated cpp file that does not have the 'extern "C" int isatty (int );'
#    signature. The Lexer is never used interactively.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
	set(lexer_fixed_src ${CMAKE_CURRENT_BINARY_DIR}/parser/Lexer.fixed.cpp)
	add_custom_command(
		OUTPUT ${lexer_fixed_src}
		COMMAND ${SED_EXECUTABLE} 's/isatty \(int \)\;/isatty \(int \) __THROW\;/' ${FLEX_Lexer_OUTPUTS} > ${lexer_fixed_src}
		DEPENDS ${FLEX_Lexer_OUTPUTS}
		COMMENT "Fixing generated FLEX source file (${lexer_fixed_src})"
		WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/parser/
	)
else(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
	set(lexer_fixed_src ${FLEX_Lexer_OUTPUTS})
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")

#
# HACKS ENDS HERE
#

# One can create a subdirectory here for each component:
set(scalar_proc_src
    LogicalExpression.cpp
    Expression.cpp
    FunctionLibrary.cpp
    FunctionDescription.cpp
    TypeSystem.cpp
    BuiltinAggregates.cpp
    TileFunctions.cpp
    Aggregate.cpp
    AggregateChunkMerger.cpp
    CompositeAggregate.cpp
    AggregateUtils.cpp
)

# FunctionLibrary.cpp includes src/query/BuiltInFunctions.h, a large
# set of C macros.  Tracking down all the expansions is too painful,
# so turn off conversion.  (There are many warnings when dealing with
# integral types smaller than int. The conversion back to sizes
# smaller than int after arithmetic operations cause the "warning:
# conversion" to occur.  ... so assume that the conversions are okay,
# and that integral-types-to-double conversions are also okay.)
#
# Also, the sheer number of function calls causes a compiler-internal
# hash table used to generate debug info to exceed its size limit, so
# turn off var-tracking assignments.  (SDB-3631)
#
if(CLANGBUILD)
  set_source_files_properties(FunctionLibrary.cpp PROPERTIES
    COMPILE_FLAGS "-Wno-conversion"
    )
else(CLANGBUILD)
  set_source_files_properties(FunctionLibrary.cpp PROPERTIES
    COMPILE_FLAGS "-Wno-conversion -fno-var-tracking-assignments"
    )
endif(CLANGBUILD)

# BuiltinAggregates.cpp include TileFunctions.h which contains templetized
# Aggregates. Many of these aggregates add/multiply by a count (of type
# uint64_t) which causes many conversion issues.
set_source_files_properties(BuiltinAggregates.cpp
  PROPERTIES
  COMPILE_FLAGS "-Wno-conversion")

add_library(scalar_proc_lib STATIC ${scalar_proc_src})
target_link_libraries(scalar_proc_lib
  PUBLIC Boost::filesystem
         Boost::program_options
         Boost::regex
         Boost::serialization
         Boost::system
         network_lib
         util_lib
  )

set(qproc_src
    optimizer/Optimizer.cpp
    optimizer/HabilisOptimizer.cpp
    LogicalPlan.cpp
    PhysicalPlan.cpp
    PhysicalQueryPlanUtilities.cpp
    LogicalQueryPlanNode.cpp
    PhysicalQueryPlanNode.cpp
    OperatorLibrary.cpp
    QueryProcessor.cpp
    Query.cpp
    QueryID.cpp
    Serialize.cpp
    executor/SciDBExecutor.cpp
    executor/ScopedQueryThread.cpp
    RemoteArray.cpp
    RemoteMergedArray.cpp
    LogicalOperator.cpp
    PhysicalOperator.cpp
    OperatorDist.cpp
    OperatorParam.cpp
    PhysicalBoundaries.cpp
    PhysicalUpdate.cpp
    OperatorProfiling.cpp
    PullSGContext.cpp
    PullSGArrayUtil.cpp
    PullSGArray.cpp
    AutochunkFixer.cpp
)

set_source_files_properties(${query_parser_src}
  PROPERTIES
  COMPILE_FLAGS "-Wno-parentheses"
  )

set_source_files_properties(${BISON_Parser_OUTPUTS}
                            ${lexer_fixed_src} # ${FLEX_Lexer_OUTPUTS} # (when HACK is removed)
  PROPERTIES
  COMPILE_FLAGS "-Wno-parentheses -Wno-conversion"
  )

add_library(qproc_lib STATIC ${qproc_src}
                             ${BISON_Parser_OUTPUTS}
                             ${lexer_fixed_src} # ${FLEX_Lexer_OUTPUTS} # (when HACK is removed)
                             ${query_parser_src}
)
# The 'register' storage class specifier is deprecated in C++11 (obsolete in C++17) but
# (some of) the version(s) of flex we use still generate code with the 'register' keyword,
# so don't warn about them.
#
# If/when we move to c++-17, the version of flex will need to be updated:
# - version 2.6.0 released 2015-11-17:
#   * Removed deprecated 'register' storage class specifier
target_compile_options(qproc_lib PRIVATE "-Wno-deprecated-register")
target_link_libraries(qproc_lib
  PUBLIC Boost::filesystem
         Boost::program_options
         Boost::regex
         Boost::serialization
         Boost::system
         rbac_lib
         monitor_lib
         scalar_proc_lib
         compression_lib
         storage_lib
         ops_lib
         system_lib
  )
