/*
 * 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 "fw_helper.hpp"

#include <geode/SystemProperties.hpp>
#include <geode/Properties.hpp>
#include <geode/CacheableString.hpp>

#ifndef WIN32
#include <unistd.h>
#endif

using apache::geode::client::Log;
using apache::geode::client::LogLevel;
using apache::geode::client::Properties;
using apache::geode::client::SystemProperties;

bool checkSecurityProperties(std::shared_ptr<Properties> securityProperties,
                             const char *key, const char *value) {
  bool flag;
  if (key == nullptr || value == nullptr) {
    return false;
  }
  auto tempValue = securityProperties->find(key);
  if (tempValue == nullptr) {
    return (false);
  }
  flag = strcmp(tempValue->value().c_str(), value);
  return (!flag);
}

BEGIN_TEST(DEFAULT)
  {
    SystemProperties *systemProperties =
        new SystemProperties(nullptr, "./non-existent");
    ASSERT(
        systemProperties->statisticsSampleInterval() == std::chrono::seconds(1),
        "expected 1");
    ASSERT(systemProperties->statisticsEnabled() == false, "expected false");
    LOG(systemProperties->statisticsArchiveFile());
    auto &&statisticsArchiveFileName =
        systemProperties->statisticsArchiveFile();
    ASSERT(statisticsArchiveFileName == "statArchive.gfs",
           "Expected statisticsArchiveFileName == \"statArchive.gfs\"");
    auto &&logLevel = Log::levelToChars(systemProperties->logLevel());
    ASSERT_STREQ("config", logLevel);
    delete systemProperties;
  }
END_TEST(DEFAULT)

BEGIN_TEST(NEW_CONFIG)
  {
    // When the tests are run from the build script the environment variable
    // TESTSRC is set.
    std::string testSource(ACE_OS::getenv("TESTSRC"));
    std::string filePath = testSource + "/resources/system.properties";

    // Make sure product can at least log to stdout.
    Log::init(LogLevel::Config, nullptr, 0);

    SystemProperties *systemProperties =
        new SystemProperties(nullptr, filePath);

    ASSERT(systemProperties->statisticsSampleInterval() ==
               std::chrono::seconds(700),
           "expected 700");

    ASSERT(systemProperties->statisticsEnabled() == true, "expected true");

    ASSERT(systemProperties->threadPoolSize() == 96,
           "max-fe-thread should be 96");

    auto &&statisticsArchiveFileName =
        systemProperties->statisticsArchiveFile();
    ASSERT1(statisticsArchiveFileName == "stats.gfs");

    auto &&logFilename = systemProperties->logFilename();
    ASSERT1(logFilename == "geode-native.log");

    auto &&name = systemProperties->name();
    ASSERT1(name == "system");

    auto &&cacheXMLFileName = systemProperties->cacheXMLFile();
    ASSERT1(cacheXMLFileName == "cache.xml");

    ASSERT(systemProperties->pingInterval() == std::chrono::seconds(123),
           "expected 123 pingInterval");
    ASSERT(systemProperties->redundancyMonitorInterval() ==
               std::chrono::seconds(456),
           "expected 456s redundancyMonitorInterval");

    ASSERT(systemProperties->heapLRULimit() == 100, "expected 100");
    ASSERT(systemProperties->heapLRUDelta() == 10, "expected 10");

    ASSERT(systemProperties->notifyAckInterval() ==
               std::chrono::milliseconds(1234),
           "expected 1234 notifyAckInterval");
    ASSERT(systemProperties->notifyDupCheckLife() ==
               std::chrono::milliseconds(4321),
           "expected 4321 notifyDupCheckLife");

    ASSERT(systemProperties->logFileSizeLimit() == 1024000000,
           "expected 1024000000");

    ASSERT(systemProperties->statsFileSizeLimit() == 1024000000,
           "expected 1024000000");

    auto &&durableId = systemProperties->durableClientId();
    ASSERT1(durableId == "testDurableId");

    ASSERT(systemProperties->durableTimeout() == std::chrono::seconds(123),
           "expected 123 durableTimeOut");

    ASSERT(systemProperties->connectTimeout() == std::chrono::milliseconds(345),
           "expected 345 for connect timeout");

    auto securityProperties = systemProperties->getSecurityProperties();
    ASSERT(checkSecurityProperties(securityProperties, "security-username",
                                   "username") == true,
           "SecurityProperties Not Stored");
    ASSERT(checkSecurityProperties(securityProperties, "security-password",
                                   "password") == true,
           "SecurityProperties Not Stored");

    delete systemProperties;
  }
END_TEST(NEW_CONFIG)
