// 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/cobalt/bin/app/cobalt_app.h"

#include <lib/gtest/test_loop_fixture.h>
#include <lib/sys/cpp/testing/component_context_provider.h>

#include <gmock/gmock.h>

#include "sdk/lib/sys/cpp/testing/service_directory_provider.h"
#include "src/cobalt/bin/app/activity_listener_impl.h"
#include "src/cobalt/bin/app/testapp_metrics_registry.cb.h"
#include "src/cobalt/bin/testing/fake_clock.h"
#include "src/cobalt/bin/testing/fake_http_loader.h"
#include "src/lib/cobalt/cpp/metric_event_builder.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "third_party/abseil-cpp/absl/strings/match.h"
#include "third_party/cobalt/src/public/testing/fake_cobalt_service.h"

namespace cobalt {

const char kTestDir[] = "/tmp/cobalt_app_test";

bool WriteFile(const std::string& file, const std::string& to_write) {
  return files::WriteFile(std::string(kTestDir) + std::string("/") + file, to_write.c_str(),
                          to_write.length());
}

class CreateCobaltConfigTest : public gtest::TestLoopFixture {
 public:
  CreateCobaltConfigTest()
      : ::gtest::TestLoopFixture(), context_provider_(), clock_(dispatcher()) {}

 protected:
  void SetUp() override {
    ASSERT_TRUE(files::DeletePath(kTestDir, true));
    ASSERT_TRUE(files::CreateDirectory(kTestDir));

    loader_ = std::make_unique<FakeHTTPLoader>(dispatcher());
    service_directory_provider_.AddService(loader_->GetHandler());
  }

  CobaltConfig CreateCobaltConfig(
      const std::string& metrics_registry_path, const FuchsiaConfigurationData& configuration_data,
      std::chrono::seconds target_interval, std::chrono::seconds min_interval,
      std::chrono::seconds initial_interval, float jitter, size_t event_aggregator_backfill_days,
      bool use_memory_observation_store, size_t max_bytes_per_observation_store,
      const std::string& product_name, const std::string& board_name, const std::string& version) {
    return CobaltApp::CreateCobaltConfig(
        dispatcher(), metrics_registry_path, configuration_data, &clock_,
        [this] {
          fuchsia::net::http::LoaderSyncPtr loader_sync;
          service_directory_provider_.service_directory()->Connect(loader_sync.NewRequest());
          return loader_sync;
        },
        UploadScheduleConfig{target_interval, min_interval, initial_interval, jitter},
        event_aggregator_backfill_days, use_memory_observation_store,
        max_bytes_per_observation_store, product_name, board_name, version,
        std::make_unique<ActivityListenerImpl>(dispatcher(), context_provider_.context()->svc()));
  }

  sys::testing::ServiceDirectoryProvider service_directory_provider_;
  std::unique_ptr<FakeHTTPLoader> loader_;

  sys::testing::ComponentContextProvider context_provider_;
  FuchsiaSystemClock clock_;
};

TEST_F(CreateCobaltConfigTest, Devel) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "DEVEL"));
  ASSERT_TRUE(WriteFile("config.json", "{\"release_stage\": \"DEBUG\"}"));
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         0, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.target_pipeline->environment(), system_data::Environment::DEVEL);
  EXPECT_EQ(config.release_stage, ReleaseStage::DEBUG);
}

TEST_F(CreateCobaltConfigTest, Local) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "LOCAL"));
  ASSERT_TRUE(WriteFile("config.json", "{\"release_stage\": \"DEBUG\"}"));
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         0, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.target_pipeline->environment(), system_data::Environment::LOCAL);
  EXPECT_EQ(config.release_stage, ReleaseStage::DEBUG);
}

TEST_F(CreateCobaltConfigTest, GA) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "DEVEL"));
  ASSERT_TRUE(WriteFile("config.json", "{\"release_stage\": \"GA\"}"));
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         0, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.target_pipeline->environment(), system_data::Environment::DEVEL);
  EXPECT_EQ(config.release_stage, ReleaseStage::GA);
}

TEST_F(CreateCobaltConfigTest, ConfigFields) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "DEVEL"));
  ASSERT_TRUE(WriteFile("config.json", "{\"release_stage\": \"GA\"}"));
  float test_jitter = .3;
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         test_jitter, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.upload_schedule_cfg.jitter, test_jitter);
}

TEST_F(CreateCobaltConfigTest, BuildTypeUser) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "DEVEL"));
  ASSERT_TRUE(WriteFile("type", "user"));
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         0, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.build_type, SystemProfile::USER);
}

TEST_F(CreateCobaltConfigTest, UnknownBuildType) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "DEVEL"));
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         0, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.build_type, SystemProfile::UNKNOWN_TYPE);
}

TEST_F(CreateCobaltConfigTest, InvalidBuildType) {
  ASSERT_TRUE(WriteFile("cobalt_environment", "DEVEL"));
  ASSERT_TRUE(WriteFile("type", "invalid"));
  FuchsiaConfigurationData configuration_data(kTestDir, kTestDir, kTestDir);
  CobaltConfig config =
      CreateCobaltConfig("/pkg/data/testapp_metrics_registry.pb", configuration_data,
                         std::chrono::seconds(1), std::chrono::seconds(2), std::chrono::seconds(3),
                         0, 4, true, 1048000, "core", "x64", "0.1.2");
  EXPECT_EQ(config.build_type, SystemProfile::OTHER_TYPE);
}

class CobaltAppTest : public gtest::TestLoopFixture {
 public:
  CobaltAppTest()
      : ::gtest::TestLoopFixture(),
        context_provider_(),
        clock_(new FakeFuchsiaSystemClock(dispatcher())),
        fake_service_(new testing::FakeCobaltService()),
        cobalt_app_(context_provider_.TakeContext(), dispatcher(),
                    std::unique_ptr<testing::FakeCobaltService>(fake_service_),
                    std::unique_ptr<FakeFuchsiaSystemClock>(clock_), true, false) {}

 protected:
  void SetUp() override {
    context_provider_.ConnectToPublicService(factory_.NewRequest());
    ASSERT_NE(factory_.get(), nullptr);
    context_provider_.ConnectToPublicService(metric_event_logger_factory_.NewRequest());
    ASSERT_NE(metric_event_logger_factory_.get(), nullptr);
  }

  // Call the LoggerFactory to create a Logger connection.
  fuchsia::cobalt::LoggerPtr GetLogger(int project_id = testapp_registry::kProjectId) {
    fuchsia::cobalt::Status status = fuchsia::cobalt::Status::INTERNAL_ERROR;
    fuchsia::cobalt::LoggerPtr logger;
    factory_->CreateLoggerFromProjectId(project_id, logger.NewRequest(),
                                        [&](fuchsia::cobalt::Status status_) { status = status_; });
    RunLoopUntilIdle();
    EXPECT_EQ(status, fuchsia::cobalt::Status::OK);
    EXPECT_NE(logger.get(), nullptr);
    return logger;
  }

  // Call the MetricEventLoggerFactory to create a Logger connection.
  fuchsia::metrics::MetricEventLoggerPtr GetMetricEventLogger(
      int project_id = testapp_registry::kProjectId) {
    fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
    fuchsia::metrics::ProjectSpec project;
    project.set_customer_id(1);
    project.set_project_id(project_id);
    fuchsia::metrics::MetricEventLoggerPtr logger;
    metric_event_logger_factory_->CreateMetricEventLogger(
        std::move(project), logger.NewRequest(),
        [&](fuchsia::metrics::Status status_) { status = status_; });
    RunLoopUntilIdle();
    EXPECT_EQ(status, fuchsia::metrics::Status::OK);
    EXPECT_NE(logger.get(), nullptr);
    return logger;
  }

  fuchsia::cobalt::Controller* GetCobaltController() { return cobalt_app_.controller_impl_.get(); }

  sys::testing::ComponentContextProvider context_provider_;
  FakeFuchsiaSystemClock* clock_;
  testing::FakeCobaltService* fake_service_;
  CobaltApp cobalt_app_;
  fuchsia::cobalt::LoggerFactoryPtr factory_;
  fuchsia::metrics::MetricEventLoggerFactoryPtr metric_event_logger_factory_;
};

TEST_F(CobaltAppTest, CreateLogger) {
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  EXPECT_EQ(fake_logger, nullptr);
  fuchsia::cobalt::LoggerPtr logger = GetLogger();
  fake_logger = fake_service_->last_logger_created();
  EXPECT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);
}

TEST_F(CobaltAppTest, CreateLoggerNoValidLogger) {
  // Make sure that the CobaltService returns nullptr for the next call to NewLogger().
  fake_service_->FailNextNewLogger();

  fuchsia::cobalt::Status status = fuchsia::cobalt::Status::OK;
  fuchsia::cobalt::LoggerPtr logger;
  factory_->CreateLoggerFromProjectId(/*project_id=*/987654321, logger.NewRequest(),
                                      [&](fuchsia::cobalt::Status status_) { status = status_; });
  RunLoopUntilIdle();
  EXPECT_EQ(status, fuchsia::cobalt::Status::INVALID_ARGUMENTS);
}

TEST_F(CobaltAppTest, CreateLoggerForNonFuchsiaCustomer) {
  fuchsia::cobalt::Status status = fuchsia::cobalt::Status::INTERNAL_ERROR;
  fuchsia::cobalt::LoggerPtr logger;
  // Use the customer and project ID for the cobalt_internal metrics project.
  factory_->CreateLoggerFromProjectSpec(/*customer_id=*/2147483647, /*project_id=*/205836624,
                                        logger.NewRequest(),
                                        [&](fuchsia::cobalt::Status status_) { status = status_; });
  RunLoopUntilIdle();
  EXPECT_EQ(status, fuchsia::cobalt::Status::OK);
  EXPECT_NE(logger.get(), nullptr);
}

TEST_F(CobaltAppTest, SystemClockIsAccurate) {
  bool callback_invoked = false;
  GetCobaltController()->ListenForInitialized([&callback_invoked]() { callback_invoked = true; });
  EXPECT_FALSE(callback_invoked);

  // Give the clock time to become accurate.
  RunLoopUntilIdle();
  EXPECT_EQ(fake_service_->system_clock_is_accurate(), true);
  EXPECT_TRUE(callback_invoked);
}

TEST_F(CobaltAppTest, LogEvent) {
  fuchsia::cobalt::LoggerPtr logger = GetLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::cobalt::Status status = fuchsia::cobalt::Status::INTERNAL_ERROR;
  logger->LogEvent(testapp_registry::kErrorOccurredMetricId, /*event_code=*/2,
                   [&](fuchsia::cobalt::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::cobalt::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 1);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kErrorOccurredMetricId);
  EXPECT_EQ(event.event_occurred_event().event_code(), 2);
}

TEST_F(CobaltAppTest, SetSoftwareDistributionInfo) {
  fuchsia::cobalt::SystemDataUpdaterPtr system_data_updater;
  context_provider_.ConnectToPublicService(system_data_updater.NewRequest());

  fuchsia::cobalt::Status status = fuchsia::cobalt::Status::INTERNAL_ERROR;
  fuchsia::cobalt::SoftwareDistributionInfo info;
  info.set_current_channel("new-channel-name");
  info.set_current_realm("new-realm-name");
  system_data_updater->SetSoftwareDistributionInfo(
      std::move(info), [&](fuchsia::cobalt::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::cobalt::Status::OK);
  EXPECT_EQ(fake_service_->system_data()->channel(), "new-channel-name");
  EXPECT_EQ(fake_service_->system_data()->realm(), "new-realm-name");
}

TEST_F(CobaltAppTest, CreateMetricEventLogger) {
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  EXPECT_EQ(fake_logger, nullptr);
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  fake_logger = fake_service_->last_logger_created();
  EXPECT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);
}

TEST_F(CobaltAppTest, CreateMetricEventLoggerNoValidLogger) {
  // Make sure that the CobaltService returns nullptr for the next call to NewLogger().
  fake_service_->FailNextNewLogger();

  fuchsia::metrics::Status status = fuchsia::metrics::Status::OK;
  fuchsia::metrics::ProjectSpec project;
  project.set_customer_id(1);
  project.set_project_id(987654321);
  fuchsia::metrics::MetricEventLoggerPtr logger;
  metric_event_logger_factory_->CreateMetricEventLogger(
      std::move(project), logger.NewRequest(),
      [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  EXPECT_EQ(status, fuchsia::metrics::Status::INVALID_ARGUMENTS);
}

TEST_F(CobaltAppTest, LogOccurrence) {
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
  logger->LogOccurrence(testapp_registry::kErrorOccurredNewMetricId, /*count=*/1,
                        /*event_codes=*/{2},
                        [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::metrics::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 1);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kErrorOccurredNewMetricId);
  EXPECT_EQ(event.occurrence_event().count(), 1);
  EXPECT_THAT(event.occurrence_event().event_code(), ::testing::ElementsAre(2));
}

TEST_F(CobaltAppTest, LogInteger) {
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
  logger->LogInteger(testapp_registry::kUpdateDurationNewMetricId, /*value=*/-42,
                     /*event_codes=*/{3},
                     [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::metrics::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 1);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kUpdateDurationNewMetricId);
  EXPECT_EQ(event.integer_event().value(), -42);
  EXPECT_THAT(event.integer_event().event_code(), ::testing::ElementsAre(3));
}

TEST_F(CobaltAppTest, LogIntegerHistogram) {
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
  std::vector<fuchsia::metrics::HistogramBucket> histogram;
  fuchsia::metrics::HistogramBucket entry;
  entry.index = 1;
  entry.count = 42;
  histogram.push_back(entry);
  logger->LogIntegerHistogram(testapp_registry::kBandwidthUsageNewMetricId, std::move(histogram),
                              /*event_codes=*/{4, 5},
                              [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::metrics::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 1);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kBandwidthUsageNewMetricId);
  EXPECT_EQ(event.integer_histogram_event().buckets().size(), 1);
  EXPECT_EQ(event.integer_histogram_event().buckets(0).index(), 1);
  EXPECT_EQ(event.integer_histogram_event().buckets(0).count(), 42);
  EXPECT_THAT(event.integer_histogram_event().event_code(), ::testing::ElementsAre(4, 5));
}

TEST_F(CobaltAppTest, LogString) {
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
  logger->LogString(testapp_registry::kErrorOccurredComponentsMetricId,
                    /*string_value=*/"component", /*event_codes=*/{3},
                    [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::metrics::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 1);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kErrorOccurredComponentsMetricId);
  EXPECT_EQ(event.string_event().string_value(), "component");
  EXPECT_THAT(event.string_event().event_code(), ::testing::ElementsAre(3));
}

TEST_F(CobaltAppTest, LogMetricEvents) {
  FX_LOGS(INFO) << "A logging statement";
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
  std::vector<fuchsia::metrics::MetricEvent> events;
  events.push_back(MetricEventBuilder(testapp_registry::kErrorOccurredNewMetricId)
                       .with_event_code(2)
                       .as_occurrence(1));
  events.push_back(MetricEventBuilder(testapp_registry::kErrorOccurredNewMetricId)
                       .with_event_code(2)
                       .as_occurrence(2));
  events.push_back(MetricEventBuilder(testapp_registry::kErrorOccurredNewMetricId)
                       .with_event_code(2)
                       .as_occurrence(3));
  events.push_back(MetricEventBuilder(testapp_registry::kErrorOccurredNewMetricId)
                       .with_event_code(2)
                       .as_occurrence(4));
  events.push_back(MetricEventBuilder(testapp_registry::kErrorOccurredNewMetricId)
                       .with_event_code(2)
                       .as_occurrence(5));
  logger->LogMetricEvents(std::move(events),
                          [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::metrics::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 5);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kErrorOccurredNewMetricId);
  EXPECT_EQ(event.occurrence_event().count(), 5);
  EXPECT_THAT(event.occurrence_event().event_code(), ::testing::ElementsAre(2));
}

TEST_F(CobaltAppTest, LogCustomEvent) {
  FX_LOGS(INFO) << "A logging statement";
  fuchsia::metrics::MetricEventLoggerPtr logger = GetMetricEventLogger();
  logger::testing::FakeLogger* fake_logger = fake_service_->last_logger_created();
  ASSERT_NE(fake_logger, nullptr);
  EXPECT_EQ(fake_logger->call_count(), 0);

  fuchsia::metrics::Status status = fuchsia::metrics::Status::INTERNAL_ERROR;
  std::vector<fuchsia::metrics::CustomEventValue> parts(3);
  parts.at(0).dimension_name = "query";
  parts.at(0).value.set_string_value("SELECT 1;");
  parts.at(1).dimension_name = "wait_time_ms";
  parts.at(1).value.set_int_value(1234);
  parts.at(2).dimension_name = "response_code";
  parts.at(2).value.set_index_value(2);
  logger->LogCustomEvent(testapp_registry::kQueryResponseMetricId, std::move(parts),
                         [&](fuchsia::metrics::Status status_) { status = status_; });
  RunLoopUntilIdle();
  ASSERT_EQ(status, fuchsia::metrics::Status::OK);
  EXPECT_EQ(fake_logger->call_count(), 1);
  auto event = fake_logger->last_event_logged();
  EXPECT_EQ(event.metric_id(), testapp_registry::kQueryResponseMetricId);
  EXPECT_EQ(event.custom_event().values().size(), 3);
  EXPECT_EQ(event.custom_event().values().at("query").string_value(), "SELECT 1;");
  EXPECT_EQ(event.custom_event().values().at("wait_time_ms").int_value(), 1234);
  EXPECT_EQ(event.custom_event().values().at("response_code").index_value(), 2);
}

TEST_F(CobaltAppTest, ShutDown) {
  EXPECT_EQ(fake_service_->is_shut_down(), false);

  fuchsia::metrics::MetricEventLoggerPtr metric_logger = GetMetricEventLogger();
  fuchsia::cobalt::LoggerPtr logger = GetLogger();
  EXPECT_TRUE(metric_logger.is_bound());
  EXPECT_TRUE(logger.is_bound());

  fuchsia::process::lifecycle::LifecyclePtr process_lifecycle;
  context_provider_.ConnectToPublicService(process_lifecycle.NewRequest(),
                                           "fuchsia.process.lifecycle.Lifecycle");
  process_lifecycle->Stop();
  RunLoopUntilIdle();
  EXPECT_EQ(fake_service_->is_shut_down(), true);
  EXPECT_FALSE(metric_logger.is_bound());
  EXPECT_FALSE(logger.is_bound());
  EXPECT_FALSE(process_lifecycle.is_bound());
}

TEST_F(CobaltAppTest, NoNewLoggersAfterShutDown) {
  fuchsia::process::lifecycle::LifecyclePtr process_lifecycle;
  context_provider_.ConnectToPublicService(process_lifecycle.NewRequest(),
                                           "fuchsia.process.lifecycle.Lifecycle");
  process_lifecycle->Stop();
  RunLoopUntilIdle();

  fuchsia::metrics::MetricEventLoggerPtr metric_logger = nullptr;
  fuchsia::cobalt::LoggerPtr logger = nullptr;
  fuchsia::cobalt::Status cobalt_status = fuchsia::cobalt::Status::INTERNAL_ERROR;
  fuchsia::metrics::Status metrics_status = fuchsia::metrics::Status::INTERNAL_ERROR;
  fuchsia::metrics::ProjectSpec project;
  project.set_customer_id(1);
  project.set_project_id(testapp_registry::kProjectId);

  metric_event_logger_factory_->CreateMetricEventLogger(
      std::move(project), metric_logger.NewRequest(),
      [&](fuchsia::metrics::Status status_) { metrics_status = status_; });
  RunLoopUntilIdle();
  EXPECT_EQ(metrics_status, fuchsia::metrics::Status::SHUT_DOWN);
  EXPECT_FALSE(metric_logger.is_bound());

  factory_->CreateLoggerFromProjectId(
      testapp_registry::kProjectId, logger.NewRequest(),
      [&](fuchsia::cobalt::Status status_) { cobalt_status = status_; });
  RunLoopUntilIdle();
  EXPECT_EQ(cobalt_status, fuchsia::cobalt::Status::SHUT_DOWN);
  EXPECT_FALSE(logger.is_bound());
}

}  // namespace cobalt
