/*
 * 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.1) Install protobuf 2.5.0 (or higher)
  $> brew install protobuf

2.2) Install zookeeper
  $> brew install zookeeper

2.3) Install boost
  $> brew install boost

2.3.1) For production builds, see the readme.boost file  
  
2.3.1.1 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 && cmake3 -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 && cmake3 -G "XCode" -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.3.1.2 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" -D CMAKE_BUILD_TYPE=Debug ..
    $> make


2.4 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.5 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




