/*
 *
 * This file is a part of the CaosDB Project.
 *
 * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
 * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 *
 */
#include "caosdb/certificate_provider.h" // for PemCertificateProvider
#include "caosdb/configuration.h"        // for InsecureConnectionConfigura...
#include "caosdb/connection.h"           // for ConnectionManager
#include "caosdb/exceptions.h"           // for UnknownConnectionError
#include "caosdb_test_utility.h"         // for EXPECT_THROW_MESSAGE, TEST_...
#include <gtest/gtest-message.h>         // for Message
#include <gtest/gtest-test-part.h>       // for SuiteApiResolver, TestPartR...
#include "gtest/gtest_pred_impl.h"       // for AssertionResult, TestInfo
#include <memory>                        // for allocator, operator!=, shar...
#include <string>                        // for operator+, string

namespace caosdb::connection {
using caosdb::configuration::ConfigurationManager;
using caosdb::configuration::InsecureConnectionConfiguration;
using caosdb::configuration::PemCertificateProvider;
using caosdb::configuration::TlsConnectionConfiguration;

class test_connection : public ::testing::Test {
protected:
  void SetUp() override {
    ConfigurationManager::Clear();
    ConfigurationManager::LoadSingleJSONConfiguration(
      TEST_DATA_DIR + "/test_caosdb_client.json");
  };
  void TearDown() override { ConfigurationManager::Clear(); };
};

TEST_F(test_connection, configure_insecure_localhost_8080) {
  InsecureConnectionConfiguration configuration("localhost", 8000);

  EXPECT_EQ("localhost", configuration.GetHost());
  EXPECT_EQ(8000, configuration.GetPort());
  auto icc = configuration.GetChannelCredentials();
  EXPECT_TRUE(icc != nullptr);
}

TEST_F(test_connection, configure_ssl_localhost_8080) {
  auto cacert = PemCertificateProvider("ca chain");
  TlsConnectionConfiguration configuration("localhost", 44300, cacert);

  EXPECT_EQ("localhost", configuration.GetHost());
  EXPECT_EQ(44300, configuration.GetPort());
  auto sslcc = configuration.GetChannelCredentials();
  EXPECT_TRUE(sslcc != nullptr);
}

// TODO(tf) cognitive complexity > 25 (threshold)
TEST_F(test_connection, connection_manager_unknown_connection) { // NOLINT
  EXPECT_THROW_MESSAGE(ConnectionManager::GetConnection("test"),
                       caosdb::exceptions::UnknownConnectionError,
                       "No connection named 'test' present.");
}

TEST_F(test_connection, connection_manager_get_default_connection) {
  auto connection = ConnectionManager::GetDefaultConnection();
  EXPECT_EQ(connection, ConnectionManager::GetConnection("local-caosdb"));
}

TEST_F(test_connection, connection_manager_get_connection) {

  EXPECT_TRUE(ConnectionManager::GetConnection("local-caosdb-admin"));
}

} // namespace caosdb::connection