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

#include <string>
#include <iostream>
#include <vector>

#include "fw_dunit.hpp"

#include <geode/internal/chrono/duration.hpp>

#define CLIENT1 s1p1
#define SERVER1 s2p1
#define SERVER2 s2p2

#include "CacheHelper.hpp"

static bool isLocalServer = false;
static bool isLocator = false;
static int numberOfLocators = 1;
const char* endPoints = (const char*)nullptr;
const char* locatorsG =
    CacheHelper::getLocatorHostPort(isLocator, isLocalServer, numberOfLocators);

#include "LocatorHelper.hpp"

using namespace apache::geode::client;
using namespace test;
using namespace std;

int testXmlDeclarativeCacheCreation() {
  char* host_name = (char*)"XML_DECLARATIVE_CACHE_CREATION_TEST";
  auto cacheFactory = CacheFactory();
  std::shared_ptr<Cache> cptr;

  std::string directory(ACE_OS::getenv("TESTSRC"));

  std::cout << "create DistributedSytem with name=" << host_name << std::endl;

  try {
    const auto filePath =
        directory + "/resources/valid_declarative_cache_creation.xml";
    cptr = std::make_shared<Cache>(
        cacheFactory.set("cache-xml-file", filePath).create());

  } catch (Exception& ex) {
    std::cout << "Exception: msg = " << ex.what() << std::endl;
    LOG(ex.getStackTrace());
    return -1;
  } catch (...) {
    LOGINFO("unknown exception");
    return -1;
  }

  std::cout << "Test if number of root regions are correct" << std::endl;
  auto vrp = cptr->rootRegions();
  std::cout << "  vrp.size=" << vrp.size() << std::endl;

  if (vrp.size() != 1) {
    std::cout << "Number of root regions does not match" << std::endl;
    return -1;
  }

  std::cout << "Root regions in Cache :" << std::endl;
  for (size_t i = 0; i < vrp.size(); i++) {
    std::cout << "vc[" << i << "].m_reaPtr=" << vrp.at(i).get() << std::endl;
    std::cout << "vc[" << i << "]=" << vrp.at(i)->getName() << std::endl;
  }
  auto regPtr1 = vrp.at(0);

  auto regionAttributes = regPtr1->getAttributes();
  std::cout << "Test Attributes of root region Root1 " << std::endl;
  std::cout << "Region name " << regPtr1->getName() << std::endl;

  if (regionAttributes.getCacheLoader() == nullptr) {
    std::cout << "Cache Loader not initialized." << std::endl;
    return -1;
  }

  if (regionAttributes.getCacheListener() == nullptr) {
    std::cout << "Cache Listener not initialized." << std::endl;
    return -1;
  }

  if (regionAttributes.getCacheWriter() == nullptr) {
    std::cout << "Cache Writer not initialized." << std::endl;
    return -1;
  }

  std::cout << "Attributes of Root1 are correctly set" << std::endl;

  if (!cptr->isClosed()) {
    cptr->close();
    cptr = nullptr;
  }

  return 0;
}

int testSetCacheXmlThenGetRegion() {
  auto cacheFactory = CacheFactory();
  std::shared_ptr<Cache> cptr;

  std::cout
      << "Create cache with the configurations provided in valid_cache_pool.xml"
      << std::endl;

  try {
    std::string filePath = "valid_cache_pool.xml";
    std::string duplicateFile;
    CacheHelper::createDuplicateXMLFile(duplicateFile, filePath);

    cptr = std::make_shared<Cache>(
        cacheFactory.set("enable-time-statistics", "false")
            .set("statistic-sampling-enabled", "false")
            .set("cache-xml-file", duplicateFile)
            .create());

  } catch (Exception& ex) {
    std::cout << "Exception: msg = " << ex.what() << std::endl;
    LOG(ex.getStackTrace());
    return -1;
  } catch (...) {
    LOGINFO("unknown exception");
    return -1;
  }

  auto region = cptr->getRegion("Root1");

  if (region == nullptr || region->getName() != "Root1") {
    return -1;
  }

  return 0;
}

DUNIT_TASK_DEFINITION(CLIENT1, ValidXmlTestDeclarativeCacheCreation)
  {
    int res = testXmlDeclarativeCacheCreation();

    if (res != 0) {
      FAIL("DeclarativeCacheCreation Test Failed.");
    }
  }
END_TASK_DEFINITION

DUNIT_TASK_DEFINITION(CLIENT1, SetCacheXmlThenGetRegion)
  {
    // Reusing server setup from ValidXmlTestPools for simplicity
    CacheHelper::initLocator(1);
    char tmp[128];
    sprintf(tmp, "localhost:%d", CacheHelper::staticLocatorHostPort1);
    CacheHelper::initServer(1, "cacheserver1_pool.xml", tmp);
    CacheHelper::initServer(2, "cacheserver2_pool.xml", tmp);

    int res = testSetCacheXmlThenGetRegion();

    CacheHelper::closeServer(1);
    CacheHelper::closeServer(2);

    CacheHelper::closeLocator(1);

    if (res != 0) {
      FAIL("SetCacheXmlThenGetRegion Test Failed.");
    }
  }
END_TASK_DEFINITION

DUNIT_MAIN
  {
    CALL_TASK(ValidXmlTestDeclarativeCacheCreation);
    CALL_TASK(SetCacheXmlThenGetRegion);
  }
END_MAIN
