// Copyright 2022 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/developer/forensics/feedback/attachments/inspect.h"

#include <fuchsia/mem/cpp/fidl.h>
#include <lib/async/cpp/executor.h>
#include <lib/fpromise/result.h>
#include <lib/inspect/cpp/vmo/types.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/time.h>

#include <memory>
#include <string>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "src/developer/forensics/feedback/attachments/types.h"
#include "src/developer/forensics/feedback_data/constants.h"
#include "src/developer/forensics/testing/gmatchers.h"
#include "src/developer/forensics/testing/gpretty_printers.h"  // IWYU pragma: keep
#include "src/developer/forensics/testing/stubs/diagnostics_archive.h"
#include "src/developer/forensics/testing/stubs/diagnostics_batch_iterator.h"
#include "src/developer/forensics/testing/unit_test_fixture.h"
#include "src/developer/forensics/utils/cobalt/logger.h"
#include "src/developer/forensics/utils/errors.h"
#include "src/developer/forensics/utils/redact/redactor.h"
#include "src/lib/timekeeper/async_test_clock.h"

namespace forensics::feedback {
namespace {

class MonotonicBackoff : public backoff::Backoff {
 public:
  static std::unique_ptr<backoff::Backoff> Make() { return std::make_unique<MonotonicBackoff>(); }

  zx::duration GetNext() override { return zx::sec(delay_++); }
  void Reset() override {}

 private:
  size_t delay_{1u};
};

class InspectTest : public UnitTestFixture {
 public:
  InspectTest()
      : executor_(dispatcher()),
        clock_(dispatcher()),
        cobalt_(dispatcher(), services(), &clock_),
        inspect_node_manager_(&InspectRoot()),
        inspect_data_budget_(std::make_unique<feedback_data::InspectDataBudget>(
            true, &inspect_node_manager_, &cobalt_)),
        redactor_(std::make_unique<IdentityRedactor>(inspect::BoolProperty())) {}

 protected:
  void SetUpInspectServer(std::unique_ptr<stubs::DiagnosticsArchiveBase> server) {
    inspect_server_ = std::move(server);
    if (inspect_server_) {
      InjectServiceProvider(inspect_server_.get(), feedback_data::kArchiveAccessorName);
    }
  }

  void DisableDataBudget() {
    inspect_data_budget_ =
        std::make_unique<feedback_data::InspectDataBudget>(false, &inspect_node_manager_, &cobalt_);
  }

  AttachmentValue Run(::fpromise::promise<AttachmentValue> promise,
                      const std::optional<zx::duration> run_loop_for = std::nullopt) {
    AttachmentValue attachment(Error::kNotSet);
    executor_.schedule_task(
        promise.and_then([&attachment](AttachmentValue& result) { attachment = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unexpected branch"; }));

    if (run_loop_for.has_value()) {
      RunLoopFor(*run_loop_for);
    } else {
      RunLoopUntilIdle();
    }

    return attachment;
  }

  RedactorBase* GetRedactor() const { return redactor_.get(); }
  void SetRedactor(std::unique_ptr<RedactorBase> redactor) { redactor_ = std::move(redactor); }

  feedback_data::InspectDataBudget* DataBudget() { return inspect_data_budget_.get(); }

 private:
  async::Executor executor_;
  timekeeper::AsyncTestClock clock_;
  cobalt::Logger cobalt_;
  InspectNodeManager inspect_node_manager_;
  std::unique_ptr<feedback_data::InspectDataBudget> inspect_data_budget_;
  std::unique_ptr<stubs::DiagnosticsArchiveBase> inspect_server_;
  std::unique_ptr<RedactorBase> redactor_;
};

TEST_F(InspectTest, DataBudget) {
  const uint64_t kTicket = 1234;
  fuchsia::diagnostics::StreamParameters parameters;
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchiveCaptureParameters>(&parameters));

  const size_t kBudget = DataBudget()->SizeInBytes().value();
  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());

  inspect.Get(kTicket);
  RunLoopUntilIdle();

  ASSERT_TRUE(parameters.has_performance_configuration());
  const auto& performance = parameters.performance_configuration();
  ASSERT_TRUE(performance.has_max_aggregate_content_size_bytes());
  ASSERT_EQ(performance.max_aggregate_content_size_bytes(), kBudget);
}

TEST_F(InspectTest, NoDataBudget) {
  const uint64_t kTicket = 1234;
  fuchsia::diagnostics::StreamParameters parameters;
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchiveCaptureParameters>(&parameters));

  DisableDataBudget();
  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());

  inspect.Get(kTicket);
  RunLoopUntilIdle();

  EXPECT_FALSE(parameters.has_performance_configuration());
}

TEST_F(InspectTest, Get) {
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchive>(
      std::make_unique<stubs::DiagnosticsBatchIterator>(std::vector<std::vector<std::string>>({
          {"foo1", "foo2"},
          {"bar1"},
          {},
      }))));

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  const auto attachment = Run(inspect.Get(1234));

  EXPECT_THAT(attachment, AttachmentValueIs(R"([
foo1,
foo2,
bar1
])"));
}

TEST_F(InspectTest, GetTerminatesDueToForceCompletion) {
  const uint64_t kTicket = 1234;
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchive>(
      std::make_unique<stubs::DiagnosticsBatchIteratorNeverRespondsAfterOneBatch>(
          std::vector<std::string>({"foo1", "foo2"}))));

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  const auto attachment = Run(inspect.Get(kTicket));

  // Giving some time to actually collect some inspect data
  RunLoopUntilIdle();

  // Forcefully terminate inspect collection
  inspect.ForceCompletion(kTicket, Error::kDefault);

  RunLoopUntilIdle();

  EXPECT_THAT(attachment, AttachmentValueIs(R"([
foo1,
foo2
])",
                                            Error::kDefault));
}

TEST_F(InspectTest, ForceCompletionCalledAfterTermination) {
  const uint64_t kTicket = 1234;
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchive>(
      std::make_unique<stubs::DiagnosticsBatchIterator>(std::vector<std::vector<std::string>>({
          {"foo1", "foo2"},
          {"bar1"},
          {},
      }))));

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  const auto attachment = Run(inspect.Get(kTicket));

  inspect.ForceCompletion(kTicket, Error::kDefault);

  EXPECT_THAT(attachment, AttachmentValueIs(R"([
foo1,
foo2,
bar1
])"));
}

TEST_F(InspectTest, GetCalledWithSameTicket) {
  const uint64_t kTicket = 1234;
  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());

  // Expect a crash because a ticket cannot be reused.
  ASSERT_DEATH(
      {
        const auto attachment1 = inspect.Get(kTicket);
        const auto attachment2 = inspect.Get(kTicket);
      },
      "Ticket used twice: ");
}

TEST_F(InspectTest, GetConnectionError) {
  const uint64_t kTicket = 1234;
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchiveClosesIteratorConnection>());

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  const auto attachment = Run(inspect.Get(kTicket));

  EXPECT_THAT(attachment.Error(), AttachmentValueIs(Error::kConnectionError));
}

TEST_F(InspectTest, GetIteratorReturnsError) {
  const uint64_t kTicket = 1234;
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchive>(
      std::make_unique<stubs::DiagnosticsBatchIteratorReturnsError>()));

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  const auto attachment = Run(inspect.Get(kTicket));

  EXPECT_THAT(attachment.Error(), AttachmentValueIs(Error::kMissingValue));
}

TEST_F(InspectTest, Reconnects) {
  fuchsia::diagnostics::StreamParameters parameters;
  auto archive = std::make_unique<stubs::DiagnosticsArchiveCaptureParameters>(&parameters);

  InjectServiceProvider(archive.get(), feedback_data::kArchiveAccessorName);

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  RunLoopUntilIdle();

  EXPECT_TRUE(archive->IsBound());

  archive->CloseConnection();
  RunLoopUntilIdle();

  EXPECT_FALSE(archive->IsBound());

  RunLoopFor(zx::sec(1));
  EXPECT_TRUE(archive->IsBound());
}

TEST_F(InspectTest, RedactsWithJsonReplacers) {
  std::string json(
      "[\"1.2.3.4\",\n"  // IPv4 Addresses are redacted
      "\"5.6.7.8\",\n"
      "\"2001::1\",\n"  // IPv6 Addresses are redacted
      "\"2001::2\",\n"
      "\"AA-BB-CC-DD-EE-FF\",\n"  // MAC Addresses are redacted with manufacturer component
                                  // unredacted
      "\"11:22:33:44:55:66\",\n"
      "1234567890abcdefABCDEF0123456789,\n"  // Long Hex numbers are not redacted
      "\"106986199446298680449\"]");         // Obfuscated Gaia IDs are not redacted
  SetUpInspectServer(std::make_unique<stubs::DiagnosticsArchive>(
      std::make_unique<stubs::DiagnosticsBatchIterator>(std::vector<std::vector<std::string>>({
          {json},
          {},
      }))));
  inspect::BoolProperty redaction_enabled;
  redaction_enabled.Set(true);
  SetRedactor(std::make_unique<Redactor>(0, inspect::UintProperty(), std::move(redaction_enabled)));

  Inspect inspect(dispatcher(), services(), MonotonicBackoff::Make(), DataBudget(), GetRedactor());
  const auto attachment = Run(inspect.Get(1234));
  EXPECT_EQ(attachment.Value(), R"([
["<REDACTED-IPV4: 1>",
"<REDACTED-IPV4: 2>",
"<REDACTED-IPV6: 3>",
"<REDACTED-IPV6: 4>",
"AA-BB-CC-<REDACTED-MAC: 5>",
"11:22:33:<REDACTED-MAC: 6>",
1234567890abcdefABCDEF0123456789,
"106986199446298680449"]
])");
}
}  // namespace
}  // namespace forensics::feedback
