/*
 * 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.
 */

#pragma once

#ifndef GEODE_INTEGRATION_TEST_QUERYHELPER_H_
#define GEODE_INTEGRATION_TEST_QUERYHELPER_H_

#include <cstdlib>

#include <ace/OS.h>

#include <geode/Region.hpp>
#include <geode/ResultSet.hpp>
#include <geode/StructSet.hpp>
#include <geode/SystemProperties.hpp>

#include "CacheImpl.hpp"
#include "CacheRegionHelper.hpp"
#include "DistributedSystemImpl.hpp"
#include "testobject/Portfolio.hpp"
#include "testobject/Position.hpp"
#include "testobject/PdxType.hpp"
#include "testobject/PortfolioPdx.hpp"
#include "testobject/PositionPdx.hpp"
#include <hacks/range.h>
#include "QueryStrings.hpp"
#include "fw_dunit.hpp"

//#include <geode/Struct.hpp>

//#ifndef ROOT_NAME
// ROOT_NAME+++ DEFINE ROOT_NAME before including QueryHelper.hpp
//#endif

#ifndef ROOT_SCOPE
#define ROOT_SCOPE LOCAL
#endif

namespace { // NOLINT(google-build-namespaces)

using apache::geode::client::CacheableKey;
using apache::geode::client::CacheableStringArray;
using apache::geode::client::CacheRegionHelper;
using apache::geode::client::Region;
using apache::geode::client::ResultSet;
using apache::geode::client::SelectResults;
using apache::geode::client::Struct;
using apache::geode::client::StructSet;
using testData::constantExpectedRowsPQRS;
using testData::constantExpectedRowsRS;
using testData::constantExpectedRowsSS;
using testData::constantExpectedRowsSSPQ;
using testobject::Portfolio;
using testobject::PortfolioPdx;
using testobject::Position;
using testobject::PositionPdx;

class QueryHelper {
 public:
  static QueryHelper* singleton;

  static QueryHelper& getHelper() {
    if (singleton == nullptr) {
      singleton = new QueryHelper();
    }
    return *singleton;
  }

  QueryHelper() {
    portfolioSetSize = 20;
    portfolioNumSets = 1;
    positionSetSize = 20;
    positionNumSets = 1;
  }

  virtual ~QueryHelper() { ; }

  virtual void populatePortfolioData(
      std::shared_ptr<Region>& pregion, size_t setSize, size_t numSets,
      int32_t objSize = 1, std::shared_ptr<CacheableStringArray> nm = nullptr);
  virtual void populatePositionData(std::shared_ptr<Region>& pregion,
                                    size_t setSize, size_t numSets);
  virtual void populatePortfolioPdxData(std::shared_ptr<Region>& pregion,
                                        size_t setSize, size_t numSets,
                                        int32_t objSize = 1,
                                        char** nm = nullptr);
  virtual void populatePositionPdxData(std::shared_ptr<Region>& pregion,
                                       size_t setSize, size_t numSets);
  virtual void populatePDXObject(std::shared_ptr<Region>& pregion);
  virtual void getPDXObject(std::shared_ptr<Region>& pregion);

  virtual bool verifyRS(std::shared_ptr<SelectResults>& resultset,
                        size_t rowCount);
  virtual bool verifySS(std::shared_ptr<SelectResults>& structset,
                        size_t rowCount, int32_t fieldCount);

  // utility methods
  virtual size_t getPortfolioSetSize() { return portfolioSetSize; }
  virtual size_t getPortfolioNumSets() { return portfolioNumSets; }
  virtual size_t getPositionSetSize() { return positionSetSize; }
  virtual size_t getPositionNumSets() { return positionNumSets; }

  bool isExpectedRowsConstantRS(int queryindex) {
    for (int i = (sizeof(constantExpectedRowsRS) / sizeof(int)) - 1; i > -1;
         i--) {
      if (constantExpectedRowsRS[i] == queryindex) {
        printf("index %d is having constant rows \n",
               constantExpectedRowsRS[i]);
        return true;
      }
    }

    return false;
  }

  bool isExpectedRowsConstantPQRS(int queryindex) {
    for (int i = (sizeof(constantExpectedRowsPQRS) / sizeof(int)) - 1; i > -1;
         i--) {
      if (constantExpectedRowsPQRS[i] == queryindex) {
        printf("index %d is having constant rows \n",
               constantExpectedRowsPQRS[i]);
        return true;
      }
    }

    return false;
  }

  bool isExpectedRowsConstantSS(int queryindex) {
    for (int i = (sizeof(constantExpectedRowsSS) / sizeof(int)) - 1; i > -1;
         i--) {
      if (constantExpectedRowsSS[i] == queryindex) {
        printf("index %d is having constant rows \n",
               constantExpectedRowsSS[i]);
        return true;
      }
    }

    return false;
  }

  bool isExpectedRowsConstantSSPQ(int queryindex) {
    for (int i = (sizeof(constantExpectedRowsSSPQ) / sizeof(int)) - 1; i > -1;
         i--) {
      if (constantExpectedRowsSSPQ[i] == queryindex) {
        printf("index %d is having constant rows \n",
               constantExpectedRowsSSPQ[i]);
        return true;
      }
    }
    return false;
  }

 private:
  size_t portfolioSetSize;
  size_t portfolioNumSets;
  size_t positionSetSize;
  size_t positionNumSets;
};

QueryHelper* QueryHelper::singleton = nullptr;

//===========================================================================================

void QueryHelper::populatePortfolioData(
    std::shared_ptr<Region>& rptr, size_t setSize, size_t numSets,
    int32_t objSize, std::shared_ptr<CacheableStringArray> nm) {
  // lets reset the counter for uniform population of position objects
  Position::resetCounter();

  for (size_t set = 1; set <= numSets; set++) {
    for (size_t current = 1; current <= setSize; current++) {
      auto port = std::make_shared<Portfolio>(static_cast<int32_t>(current),
                                              objSize, nm);

      char portname[100] = {0};
      ACE_OS::sprintf(portname, "port%zd-%zd", set, current);

      auto keyport = CacheableKey::create(portname);
      // printf(" QueryHelper::populatePortfolioData creating key = %s and
      // puting data \n",portname);
      rptr->put(keyport, port);
    }
  }
  // portfolioSetSize = setSize; portfolioNumSets = numSets; objectSize =
  // objSize;

  printf("all puts done \n");
}

const char* secIds[] = {"SUN", "IBM",  "YHOO", "GOOG", "MSFT",
                        "AOL", "APPL", "ORCL", "SAP",  "DELL"};

void QueryHelper::populatePositionData(std::shared_ptr<Region>& rptr,
                                       size_t setSize, size_t numSets) {
  int numSecIds = sizeof(secIds) / sizeof(char*);

  for (size_t set = 1; set <= numSets; set++) {
    for (size_t current = 1; current <= setSize; current++) {
      auto pos = std::make_shared<Position>(
          secIds[current % numSecIds], static_cast<int32_t>(current * 100));

      char posname[100] = {0};
      ACE_OS::sprintf(posname, "pos%zd-%zd", set, current);

      auto keypos = CacheableKey::create(posname);
      rptr->put(keypos, pos);
    }
  }
  // positionSetSize = setSize; positionNumSets = numSets;
}

void QueryHelper::populatePortfolioPdxData(std::shared_ptr<Region>& rptr,
                                           size_t setSize, size_t numSets,
                                           int32_t objSize, char**) {
  // lets reset the counter for uniform population of position objects
  PositionPdx::resetCounter();

  for (size_t set = 1; set <= numSets; set++) {
    for (size_t current = 1; current <= setSize; current++) {
      auto port = std::make_shared<PortfolioPdx>(static_cast<int32_t>(current),
                                                 objSize);

      char portname[100] = {0};
      ACE_OS::sprintf(portname, "port%zd-%zd", set, current);

      auto keyport = CacheableKey::create(portname);

      rptr->put(keyport, port);
      LOGDEBUG("populatePortfolioPdxData:: Put for iteration current = %d done",
               current);
    }
  }
  // portfolioSetSize = setSize; portfolioNumSets = numSets; objectSize =
  // objSize;

  printf("all puts done \n");
}

void QueryHelper::populatePositionPdxData(std::shared_ptr<Region>& rptr,
                                          size_t setSize, size_t numSets) {
  auto numSecIds = sizeof(secIds) / sizeof(char*);

  for (size_t set = 1; set <= numSets; set++) {
    for (size_t current = 1; current <= setSize; current++) {
      auto pos = std::make_shared<PositionPdx>(
          secIds[current % numSecIds], static_cast<int32_t>(current * 100));

      char posname[100] = {0};
      ACE_OS::sprintf(posname, "pos%zd-%zd", set, current);

      auto keypos = CacheableKey::create(posname);
      rptr->put(keypos, pos);
    }
  }
  // positionSetSize = setSize; positionNumSets = numSets;
}

void QueryHelper::populatePDXObject(std::shared_ptr<Region>& rptr) {
  // Register PdxType Object

  auto cacheImpl = CacheRegionHelper::getCacheImpl(&rptr->getCache());
  cacheImpl->getSerializationRegistry()->addPdxSerializableType(
      PdxTests::PdxType::createDeserializable);
  LOG("PdxObject Registered Successfully....");

  // Creating object of type PdxObject
  auto pdxobj = std::make_shared<PdxTests::PdxType>();
  auto keyport = CacheableKey::create("ABC");

  // PUT Operation
  rptr->put(keyport, pdxobj);

  // locally destroy PdxObject
  rptr->localDestroy(keyport);
  LOG("localDestroy() operation....Done");

  // Remote GET for PdxObject
  auto obj2 = std::dynamic_pointer_cast<PdxTests::PdxType>(rptr->get(keyport));

  LOGINFO("get... Result-1: Returned float=%f, String val = %s double=%lf",
          obj2->getFloat(), obj2->getString().c_str(), obj2->getDouble());
  // LOGINFO("get.. Result-2: Returned BOOL = %d and BYTE = %s SHORT=%d INT=%d",
  // obj2->getBool(), obj2->getByte(), obj2->getShort(), obj2->getInt());

  // TODO
  /*
  ASSERT(obj2->getID1() == 101, "ID1 = 101 expected");
  ASSERT(obj2->getID2() == 201, "ID2 = 201 expected");
  ASSERT(obj2->getID3() == 301, "ID3 = 301 expected");
  */

  LOG("NIL:200:PUT Operation successfully Done....End");
}

void QueryHelper::getPDXObject(std::shared_ptr<Region>& rptr) {
  // Remote GET for PdxObject
  // PdxObject *obj2 = dynamic_cast<PdxObject *> ((rptr->get(keyport)).get());

  auto keyport = CacheableKey::create("ABC");
  LOG("Client-2 PdxObject GET OP Start....");
  auto obj2 = std::dynamic_pointer_cast<PdxTests::PdxType>(rptr->get(keyport));
  LOG("Client-2 PdxObject GET OP Done....");

  /*
  LOGINFO("GET OP Result: BoolVal=%d", obj2->getBool());
  LOGINFO("GET OP Result: ByteVal=%d", obj2->getByte());
  LOGINFO("GET OP Result: ShortVal=%d", obj2->getShort());*/

  // LOGINFO("GET OP Result: IntVal=%d", obj2->getInt());
  /*
  LOGINFO("GET OP Result: LongVal=%ld", obj2->getLong());
  LOGINFO("GET OP Result: FloatVal=%f", obj2->getFloat());
  LOGINFO("GET OP Result: DoubleVal=%lf", obj2->getDouble());
  LOGINFO("GET OP Result: StringVal=%s", obj2->getString());
  */
}

bool QueryHelper::verifyRS(std::shared_ptr<SelectResults>& resultSet,
                           size_t expectedRows) {
  if (auto rsptr = std::static_pointer_cast<ResultSet>(resultSet)) {
    size_t foundRows = 0;
    for (auto&& row : hacks::range(*rsptr)) {
      foundRows++;
    }

    printf("found rows %zd, expected %zd \n", foundRows, expectedRows);
    if (foundRows == expectedRows) return true;
  }
  return false;
}

bool QueryHelper::verifySS(std::shared_ptr<SelectResults>& structSet,
                           size_t expectedRows, int32_t expectedFields) {
  if (auto ssptr = std::static_pointer_cast<StructSet>(structSet)) {
    size_t foundRows = 0;
    for (auto&& ser : hacks::range(*ssptr)) {
      foundRows++;

      auto siptr = std::dynamic_pointer_cast<Struct>(ser);

      if (siptr == nullptr) {
        printf("siptr is nullptr \n\n");
        return false;
      }

      int32_t foundFields = 0;
      for (auto&& field : *siptr) {
        foundFields++;
      }

      if (foundFields != expectedFields) {
        char buffer[1024] = {'\0'};
        sprintf(buffer, "found fields %d, expected fields %d \n", foundFields,
                expectedFields);
        LOG(buffer);
        return false;
      }
    }

    if (foundRows == expectedRows) return true;

    // lets log and return in case of error only situation
    char buffer[1024] = {'\0'};
    sprintf(buffer, "found rows %zd, expected rows %zd\n", foundRows,
            expectedRows);
    LOG(buffer);
  } else {
    if (expectedRows == 0 && expectedFields == 0) {
      return true;  // quite possible we got a null set back.
    }
  }
  return false;
}

}  // namespace

#endif  // GEODE_INTEGRATION_TEST_QUERYHELPER_H_
