// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/public/cobalt_service.h"

#include <gtest/gtest.h>

#include "src/lib/util/posix_file_system.h"
#include "third_party/abseil-cpp/absl/strings/escaping.h"

namespace cobalt {

using observation_store::ObservationStore;
using uploader::ClearcutV1ShippingManager;
using uploader::ShippingManager;

namespace {

CobaltConfig MinConfigForTesting() {
  CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

  cfg.file_system = std::make_unique<util::PosixFileSystem>();
  cfg.target_pipeline = std::make_unique<LocalPipeline>();

  cfg.observation_store_directory = "/tmp/a";
  cfg.local_aggregate_proto_store_path = "/tmp/b";
  cfg.obs_history_proto_store_path = "/tmp/c";
  cfg.local_aggregate_store_dir = "/tmp/d";
  cfg.system_data_cache_path = "/tmp/e";

  return cfg;
}

std::unique_ptr<TargetPipeline> MinClearcutTargetPipeline() {
  return std::make_unique<TargetPipeline>(system_data::Environment::DEVEL,
                                          /*shuffler_encryption_key=*/"",
                                          /*analyzer_encryption_key=*/"", /*http_client=*/nullptr);
}

}  // namespace

class CobaltServiceTest : public ::testing::Test {
 protected:
  // Gives access to the private getter method shipping_manager() for the
  // given |cobalt_service|.
  static ShippingManager* GetShippingManager(CobaltService* cobalt_service) {
    return cobalt_service->shipping_manager();
  }

  // Gives access to the private getter method observation_store() for the
  // given |cobalt_service|.
  static ObservationStore* GetObservationStore(CobaltService* cobalt_service) {
    return cobalt_service->observation_store();
  }

  // Gives access to the private getter method civil_time_converter() for the
  // given |cobalt_service|.
  static util::CivilTimeConverterInterface* GetCivilTimeConverter(CobaltService* cobalt_service) {
    return cobalt_service->civil_time_converter();
  }
};

TEST_F(CobaltServiceTest, CrashesWhenConstructingWithNoGlobalRegistry) {
  auto cfg = MinConfigForTesting();
  cfg.global_registry = nullptr;
  ASSERT_DEATH(CobaltService service(std::move(cfg)), "Cannot initialize store");
}

TEST_F(CobaltServiceTest, DoesNotCreateInternalLoggerWithEmptyGlobalRegistry) {
  auto cfg = MinConfigForTesting();
  cfg.global_registry = std::make_unique<CobaltRegistry>();
  CobaltService service(std::move(cfg));
  EXPECT_FALSE(service.has_internal_logger());
  ShippingManager* shipping_manager = GetShippingManager(&service);
  EXPECT_TRUE(shipping_manager->impl() == ShippingManager::Impl::OTHER);
  ObservationStore* observation_store = GetObservationStore(&service);
  EXPECT_FALSE(observation_store->internal_metrics()->IsRealImpl());
}

TEST_F(CobaltServiceTest, CreatesInternalLoggerWithValidRegistry) {
  auto cfg = MinConfigForTesting();
  cfg.global_registry = std::make_unique<CobaltRegistry>();
  std::string registry_bytes;
  ASSERT_TRUE(absl::Base64Unescape(cobalt::logger::kConfig, &registry_bytes));
  ASSERT_TRUE(cfg.global_registry->ParseFromString(registry_bytes));
  CobaltService service(std::move(cfg));
  EXPECT_TRUE(service.has_internal_logger());
  ShippingManager* shipping_manager = GetShippingManager(&service);
  EXPECT_TRUE(shipping_manager->impl() == ShippingManager::Impl::OTHER);
  ObservationStore* observation_store = GetObservationStore(&service);
  EXPECT_TRUE(observation_store->internal_metrics()->IsRealImpl());
}

// Tests that when a real ClearcutV1ShippingManager is used that it
// gets a real internal logger to use.
TEST_F(CobaltServiceTest, CreatesClearcutV1ShippingManager) {
  auto cfg = MinConfigForTesting();
  cfg.global_registry = std::make_unique<CobaltRegistry>();
  cfg.target_pipeline = MinClearcutTargetPipeline();
  std::string registry_bytes;
  ASSERT_TRUE(absl::Base64Unescape(cobalt::logger::kConfig, &registry_bytes));
  ASSERT_TRUE(cfg.global_registry->ParseFromString(registry_bytes));
  CobaltService service(std::move(cfg));
  EXPECT_TRUE(service.has_internal_logger());
  ShippingManager* shipping_manager = GetShippingManager(&service);
  ASSERT_TRUE(shipping_manager->impl() == ShippingManager::Impl::CLEARCUTV1);
  const auto* clearcut_shipping = static_cast<const ClearcutV1ShippingManager*>(shipping_manager);
  EXPECT_TRUE(clearcut_shipping->internal_metrics()->IsRealImpl());
  EXPECT_TRUE(clearcut_shipping->clearcut_uploader()->internal_metrics()->IsRealImpl());
  ObservationStore* observation_store = GetObservationStore(&service);
  EXPECT_TRUE(observation_store->internal_metrics()->IsRealImpl());
}

TEST_F(CobaltServiceTest, CreatesDefaultCivilTimeConverter) {
  auto cfg = MinConfigForTesting();
  ASSERT_FALSE(cfg.civil_time_converter);
  cfg.global_registry = std::make_unique<CobaltRegistry>();
  CobaltService service(std::move(cfg));
  EXPECT_TRUE(GetCivilTimeConverter(&service));
}

}  // namespace cobalt
