/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
MacOS build (tested on OS X El Capitan)

Install Prerequisites
---------------------

0.1) Install XCode 
  Download and install from here: https://developer.apple.com/xcode/downloads/
  or from the App store https://itunes.apple.com/us/app/xcode/id497799835?mt=12
  In Terminal, install the command line tools 
    $> xcode-select --install

0.2) Install brew following the instructions here: http://brew.sh/

1) CMAKE 3.0 or above
  Download and install Cmake : https://cmake.org/download/
  or use brew to install 
  $> brew install cmake

2.0) Install cppunit 
  $> brew install cppunit 

2.1) Install protobuf 2.5.0 (or higher)
  $> brew install protobuf

2.2) Install zookeeper
  $> brew install zookeeper

2.3) Install or build Cyrus SASL 
   To Install (need macports, brew did not work for me)
       port install cyrus-sasl2

   To build your own 
   See readme.sasl for instructions

2.4) Install OpenSSL
   [NOTE: MacOS has a neutered version of openssl installed. Install the build using brew. Make sure the brew installation is picked up]
   brew install openssl

2.5) Install boost
  $> brew install boost

2.5.1) For production builds, see the readme.boost file  
  
2.6) Build using XCODE
=========================  
(Optional) Refresh protobuf source files
----------------------------------------
When changes have been introduced to the protocol module, you might need to refresh the protobuf C++ source files too.
  $> cd DRILL_DIR/contrib/native/client
  $> mkdir build
  $> cd build && cmake -G "Xcode" -D CMAKE_BUILD_TYPE=Debug ..
  $> xcodebuild -project drillclient.xcodeproj -configuration ${BUILDTYPE} -target fixProtobufs
  $> xcodebuild -project drillclient.xcodeproj -configuration ${BUILDTYPE} -target cpProtobufs

Open a pull request with the changes to DRILL_DIR/contrib/native/client/src/protobuf

Build drill client
-------------------
  $> cd DRILL_DIR/contrib/native/client
  $> mkdir build
  $> cd build && cmake -G "Xcode" -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl "-D CMAKE_BUILD_TYPE=Debug ..
  $> xcodebuild -project drillclient.xcodeproj -configuration ${BUILDTYPE} -target ALL_BUILD


XCode IDE
---------
  You can open the drillclient.xcodeproj file in the XCode ide and run/debug as with any other command line app

2.7) Build using MAKE
========================
(Optional) Refresh protobuf source files
----------------------------------------
When changes have been introduced to the protocol module, you might need to refresh the protobuf C++ source files too.
    $> cd DRILL_DIR/contrib/native/client
    $> mkdir build
    $> cd build && cmake3 -G "Unix Makefiles" ..
    $> make cpProtobufs

Open a pull request with the changes to DRILL_DIR/contrib/native/client/src/protobuf

Build drill client
-------------------
    $> cd DRILL_DIR/contrib/native/client
    $> mkdir build
    $> cd build && cmake3 -G "Unix Makefiles" -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl" -D CMAKE_BUILD_TYPE=Debug ..
    $> make

2.10) Build using CLion
CLion can recognize cmake projects automatically. Check CLion documentation for help on how to use CMake with CLion.
To prevent CLion's cmake from picking up the system installed OpenSSL set the following define in CLion/Preferences/Build, Execution, Deployment/CMake/CMake Options
-DOPENSSL_ROOT_DIR="/usr/local/opt/openssl
Then reload the CMake project making sure to invalidate the CMake cache
Tools/CMake/Reset Cache and Reload Project

2.9 Test
--------
Run query submitter from the command line
  $> querySubmitter query='select * from dfs.`/Users/pchandra/work/data/tpc-h/customer.parquet`' type=sql connectStr=local=10.250.0.146:31010 api=async logLevel=trace user=yourUserName password=yourPassWord

2.10 Valgrind
------------
  Install valgrind using brew
  $> brew install valgrind
  $> valgrind --leak-check=yes querySubmitter query='select LINEITEM from dfs.`/Users/pchandra/work/data/tpc-h/customer.parquet`' type=sql connectStr=local=10.250.0.146:31010 api=async logLevel=trace




