/* Copyright (C) 2014 InfiniDB, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; version 2 of
   the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301, USA. */

//
// $Id: funcexpwrapper.cpp 3495 2013-01-21 14:09:51Z rdempsey $
//
// C++ Implementation: funcexpwrapper
//
// Description:
//
//
// Author: Patrick LeBlanc <pleblanc@calpont.com>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include "funcexpwrapper.h"
#include "objectreader.h"

using namespace messageqcpp;
using namespace rowgroup;
using namespace execplan;

namespace funcexp
{
FuncExpWrapper::FuncExpWrapper()
{
  fe = FuncExp::instance();
}

FuncExpWrapper::FuncExpWrapper(const FuncExpWrapper& f)
{
  uint32_t i;

  fe = FuncExp::instance();

  filters.resize(f.filters.size());

  for (i = 0; i < f.filters.size(); i++)
    filters[i].reset(new ParseTree(*(f.filters[i])));

  rcs.resize(f.rcs.size());

  for (i = 0; i < f.rcs.size(); i++)
    rcs[i].reset(f.rcs[i]->clone());
}

FuncExpWrapper::~FuncExpWrapper()
{
}

void FuncExpWrapper::operator=(const FuncExpWrapper& f)
{
  uint32_t i;

  filters.resize(f.filters.size());

  for (i = 0; i < f.filters.size(); i++)
    filters[i].reset(new ParseTree(*(f.filters[i])));

  rcs.resize(f.rcs.size());

  for (i = 0; i < f.rcs.size(); i++)
    rcs[i].reset(f.rcs[i]->clone());
}

void FuncExpWrapper::serialize(ByteStream& bs) const
{
  uint32_t i;

  bs << (uint32_t)filters.size();
  bs << (uint32_t)rcs.size();

  for (i = 0; i < filters.size(); i++)
    ObjectReader::writeParseTree(filters[i].get(), bs);

  for (i = 0; i < rcs.size(); i++)
    rcs[i]->serialize(bs);
}

void FuncExpWrapper::deserialize(ByteStream& bs)
{
  uint32_t fCount, rcsCount, i;

  bs >> fCount;
  bs >> rcsCount;

  for (i = 0; i < fCount; i++)
    filters.push_back(boost::shared_ptr<ParseTree>(ObjectReader::createParseTree(bs)));

  for (i = 0; i < rcsCount; i++)
  {
    ReturnedColumn* rc = (ReturnedColumn*)ObjectReader::createTreeNode(bs);
    rcs.push_back(boost::shared_ptr<ReturnedColumn>(rc));
  }
}

bool FuncExpWrapper::evaluate(Row* r)
{
  uint32_t i;

  for (i = 0; i < filters.size(); i++)
    if (!fe->evaluate(*r, filters[i].get()))
      return false;

  fe->evaluate(*r, rcs);

  return true;
}

void FuncExpWrapper::addFilter(const boost::shared_ptr<ParseTree>& f)
{
  filters.push_back(f);
}

void FuncExpWrapper::addReturnedColumn(const boost::shared_ptr<ReturnedColumn>& rc)
{
  rcs.push_back(rc);
}

};  // namespace funcexp
