/*
 *
 * 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/configuration.h"
#include "caosdb/status_code.h"    // for StatusCode
#include "caosdb_test_utility.h"   // for EXPECT_THROW_MESSAGE, TEST_DATA_DIR
#include "ccaosdb.h"               // for caosdb_utility_get_env_var
#include <gtest/gtest-message.h>   // for Message
#include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestFactoryImpl
#include <gtest/gtest_pred_impl.h> // for Test, TestInfo, EXPECT_EQ, TEST
#include <string>                  // for allocator

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

  void TearDown() override {
    caosdb::configuration::ConfigurationManager::Clear();
  }
};

TEST_F(test_ccaosdb, test_get_env_var) {
  const char *const some_var =
    caosdb_utility_get_env_var("SOME_ENV_VAR", "fall-back");
  EXPECT_EQ("fall-back", some_var);
}

TEST_F(test_ccaosdb, test_get_default_connection) {
  caosdb_connection_connection out;

  caosdb_connection_connection_manager_get_default_connection(&out);
  EXPECT_TRUE(out.wrapped_connection);
}

TEST_F(test_ccaosdb, test_get_connection) {
  caosdb_connection_connection out;

  caosdb_connection_connection_manager_get_connection(&out,
                                                      "local-caosdb-admin");
  EXPECT_TRUE(out.wrapped_connection);
}

TEST_F(test_ccaosdb, test_execute_transaction) {
  caosdb_connection_connection connection;
  caosdb_connection_connection_manager_get_connection(&connection,
                                                      "local-caosdb-admin");

  caosdb_transaction_transaction transaction;
  caosdb_connection_connection_create_transaction(&connection, &transaction);

  EXPECT_TRUE(transaction.wrapped_transaction);

  int return_code(
    caosdb_transaction_transaction_retrieve_by_id(&transaction, "some_id"));
  EXPECT_EQ(return_code, 0);

  return_code = caosdb_transaction_transaction_execute(&transaction);
  EXPECT_EQ(return_code, caosdb::StatusCode::CONNECTION_ERROR);

  caosdb_transaction_transaction multi_transaction;
  caosdb_connection_connection_create_transaction(&connection,
                                                  &multi_transaction);

  // We explicitely want to define a C-style array here, so we disable
  // linting
  const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
  return_code =
    caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids);
  EXPECT_EQ(return_code, 0);
}

TEST_F(test_ccaosdb, test_multi_retrieve) {
  caosdb_connection_connection connection;
  caosdb_connection_connection_manager_get_connection(&connection,
                                                      "local-caosdb-admin");

  caosdb_transaction_transaction multi_transaction;
  caosdb_connection_connection_create_transaction(&connection,
                                                  &multi_transaction);

  // We explicitely want to define a C-style array here, so we disable
  // linting
  const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
  int return_code(
    caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids));
  EXPECT_EQ(return_code, 0);
}