// 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();
  }
};

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());
}

}  // namespace cobalt
