// 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/annotations/annotation_manager.h"

#include <lib/async/cpp/executor.h>
#include <lib/async/cpp/task.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/time.h>

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

#include "src/developer/forensics/feedback/annotations/provider.h"
#include "src/developer/forensics/feedback/annotations/types.h"
#include "src/developer/forensics/testing/unit_test_fixture.h"

namespace forensics::feedback {
namespace {

using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::UnorderedElementsAreArray;

constexpr bool kIsMissingNonPlatform = true;
constexpr bool kNotIsMissingNonPlatform = false;

auto MakePair(const char* key, const char* value) { return Pair(key, ErrorOr<std::string>(value)); }
auto MakePair(const char* key, const Error error) { return Pair(key, ErrorOr<std::string>(error)); }

class DynamicNonPlatform : public NonPlatformAnnotationProvider {
 public:
  DynamicNonPlatform(const bool exempt = kNotIsMissingNonPlatform)
      : is_missing_annotations_(exempt) {}

  Annotations Get() override {
    ++calls_;
    if (is_missing_annotations_) {
      return {};
    }

    return {{"num_calls", std::to_string(calls_)}};
  }

  bool IsMissingAnnotations() const override { return is_missing_annotations_; }

 private:
  size_t calls_{0};
  bool is_missing_annotations_;
};

using AnnotationManagerTest = UnitTestFixture;

TEST_F(AnnotationManagerTest, ImmediatelyAvailable) {
  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  DynamicNonPlatform non_platform;

  {
    AnnotationManager manager(dispatcher(), {"annotation1", "annotation2", "num_calls"},
                              static_annotations, &non_platform);

    EXPECT_THAT(manager.ImmediatelyAvailable(), UnorderedElementsAreArray({
                                                    MakePair("annotation1", "value1"),
                                                    MakePair("annotation2", Error::kMissingValue),
                                                    MakePair("num_calls", "1"),
                                                }));
  }
}

TEST_F(AnnotationManagerTest, StaticAllowlist) {
  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  DynamicNonPlatform counter;
  {
    AnnotationManager manager(dispatcher(), {}, static_annotations, nullptr, {&counter});

    EXPECT_THAT(manager.ImmediatelyAvailable(), IsEmpty());
  }

  {
    AnnotationManager manager(dispatcher(), {"annotation1"}, static_annotations, nullptr,
                              {&counter});

    EXPECT_THAT(manager.ImmediatelyAvailable(), UnorderedElementsAreArray({
                                                    MakePair("annotation1", "value1"),
                                                }));
  }

  {
    AnnotationManager manager(dispatcher(), {"annotation1", "num_calls"}, static_annotations,
                              nullptr, {&counter});

    EXPECT_THAT(manager.ImmediatelyAvailable(), UnorderedElementsAreArray({
                                                    MakePair("annotation1", "value1"),
                                                    MakePair("num_calls", "3"),
                                                }));
  }
}

TEST_F(AnnotationManagerTest, IsNotMissingNonPlatform) {
  DynamicNonPlatform non_platform(kNotIsMissingNonPlatform);

  {
    AnnotationManager manager(dispatcher(), {}, {}, &non_platform);
    EXPECT_THAT(manager.ImmediatelyAvailable(), UnorderedElementsAreArray({
                                                    MakePair("num_calls", "1"),
                                                }));
    EXPECT_FALSE(manager.IsMissingNonPlatformAnnotations());
  }
}

TEST_F(AnnotationManagerTest, IsMissingNonPlatform) {
  DynamicNonPlatform non_platform(kIsMissingNonPlatform);

  {
    AnnotationManager manager(dispatcher(), {}, {}, &non_platform);

    EXPECT_THAT(manager.ImmediatelyAvailable(), IsEmpty());
    EXPECT_TRUE(manager.IsMissingNonPlatformAnnotations());
  }
}

TEST_F(AnnotationManagerTest, UniqueKeys) {
  ASSERT_DEATH(
      {
        AnnotationManager manager(dispatcher(), {"annotation1"});
        manager.InsertStatic({{"annotation1", "value1"}});
        manager.InsertStatic({{"annotation1", "value2"}});
      },
      "Attempting to re-insert annotation1");
}

class SimpleStaticAsync : public StaticAsyncAnnotationProvider {
 public:
  SimpleStaticAsync(async_dispatcher_t* dispatcher, Annotations annotations,
                    const zx::duration delay = zx::sec(0))
      : dispatcher_(dispatcher), annotations_(std::move(annotations)), delay_(delay) {}

  std::set<std::string> GetKeys() const override {
    std::set<std::string> keys;
    for (const auto& [k, _] : annotations_) {
      keys.insert(k);
    }

    return keys;
  }

  void GetOnce(::fit::callback<void(Annotations)> callback) override {
    async::PostDelayedTask(
        dispatcher_, [this, cb = std::move(callback)]() mutable { cb(annotations_); }, delay_);
  }

 private:
  async_dispatcher_t* dispatcher_;
  Annotations annotations_;
  zx::duration delay_;
};

TEST_F(AnnotationManagerTest, GetAllNoStaticAsyncProviders) {
  async::Executor executor(dispatcher());

  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  DynamicNonPlatform non_platform;

  {
    AnnotationManager manager(dispatcher(), {"annotation1", "annotation2", "num_calls"},
                              static_annotations, &non_platform);

    Annotations annotations;

    // Use a timeout of 0 because only immediately available annotations are returned.
    executor.schedule_task(
        manager.GetAll(zx::sec(0))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopUntilIdle();
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "1"),
                             }));
  }
}

TEST_F(AnnotationManagerTest, GetAllStaticAsyncProviders) {
  async::Executor executor(dispatcher());

  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  SimpleStaticAsync immediate_static(dispatcher(), {
                                                       {"annotation3", "value3"},
                                                   });
  SimpleStaticAsync five_second_static(dispatcher(),
                                       {
                                           {"annotation4", "value4"},
                                       },
                                       zx::sec(5));
  SimpleStaticAsync ten_second_static(dispatcher(),
                                      {
                                          {"annotation5", "value5"},
                                      },
                                      zx::sec(10));
  DynamicNonPlatform non_platform;

  AnnotationManager manager(dispatcher(),
                            {
                                "annotation1",
                                "annotation2",
                                "num_calls",
                                "annotation3",
                                "annotation4",
                                "annotation5",
                            },
                            static_annotations, &non_platform, {},
                            {&immediate_static, &five_second_static, &ten_second_static});
  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(0))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopUntilIdle();
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "1"),
                                 MakePair("annotation3", "value3"),
                                 MakePair("annotation4", Error::kTimeout),
                                 MakePair("annotation5", Error::kTimeout),
                             }));
  }

  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(5))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopFor(zx::sec(5));
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "2"),
                                 MakePair("annotation3", "value3"),
                                 MakePair("annotation4", "value4"),
                                 MakePair("annotation5", Error::kTimeout),
                             }));
  }

  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(5))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopFor(zx::sec(5));
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "3"),
                                 MakePair("annotation3", "value3"),
                                 MakePair("annotation4", "value4"),
                                 MakePair("annotation5", "value5"),
                             }));
  }
}

class SimpleDynamicAsync : public DynamicAsyncAnnotationProvider {
 public:
  SimpleDynamicAsync(async_dispatcher_t* dispatcher, std::set<std::string> keys,
                     const zx::duration delay = zx::sec(0))
      : dispatcher_(dispatcher), keys_(std::move(keys)), delay_(delay) {}

  std::set<std::string> GetKeys() const override { return keys_; }

  void Get(::fit::callback<void(Annotations)> callback) override {
    async::PostDelayedTask(
        dispatcher_,
        [this, cb = std::move(callback)]() mutable {
          const std::string value = "call" + std::to_string(++count_);

          Annotations annotations;
          for (const auto& key : keys_) {
            annotations.insert_or_assign(key, value);
          }
          cb(annotations);
        },
        delay_);
  }

 private:
  async_dispatcher_t* dispatcher_;
  std::set<std::string> keys_;
  zx::duration delay_;

  size_t count_{0};
};

TEST_F(AnnotationManagerTest, GetAllNoDyanmicAsyncProviders) {
  async::Executor executor(dispatcher());

  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  DynamicNonPlatform non_platform;

  {
    AnnotationManager manager(dispatcher(), {"annotation1", "annotation2", "num_calls"},
                              static_annotations, &non_platform);

    Annotations annotations;

    // Use a timeout of 0 because only immediately available annotations are returned.
    executor.schedule_task(
        manager.GetAll(zx::sec(0))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopUntilIdle();
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "1"),
                             }));
  }
}

TEST_F(AnnotationManagerTest, GetAllDynamicAsyncProviders) {
  async::Executor executor(dispatcher());

  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  SimpleDynamicAsync immediate_dynamic(dispatcher(), {"annotation3"});
  SimpleDynamicAsync five_second_dynamic(dispatcher(), {"annotation4"}, zx::sec(5));
  SimpleDynamicAsync ten_second_dynamic(dispatcher(), {"annotation5"}, zx::sec(10));
  DynamicNonPlatform non_platform;

  AnnotationManager manager(dispatcher(),
                            {
                                "annotation1",
                                "annotation2",
                                "num_calls",
                                "annotation3",
                                "annotation4",
                                "annotation5",
                            },
                            static_annotations, &non_platform, {}, {},
                            {&immediate_dynamic, &five_second_dynamic, &ten_second_dynamic});
  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(0))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopUntilIdle();
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "1"),
                                 MakePair("annotation3", "call1"),
                                 MakePair("annotation4", Error::kTimeout),
                                 MakePair("annotation5", Error::kTimeout),
                             }));
  }

  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(5))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopFor(zx::sec(5));
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "2"),
                                 MakePair("annotation3", "call2"),
                                 MakePair("annotation4", "call2"),
                                 MakePair("annotation5", Error::kTimeout),
                             }));
  }

  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(10))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopFor(zx::sec(10));
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "3"),
                                 MakePair("annotation3", "call3"),
                                 MakePair("annotation4", "call3"),
                                 MakePair("annotation5", "call3"),
                             }));
  }
}

TEST_F(AnnotationManagerTest, GetAll) {
  async::Executor executor(dispatcher());

  const Annotations static_annotations({
      {"annotation1", "value1"},
      {"annotation2", Error::kMissingValue},
  });

  SimpleStaticAsync three_second_static(dispatcher(), {{"annotation3", "value3"}}, zx::sec(3));
  SimpleDynamicAsync five_second_dynamic(dispatcher(), {"annotation4"}, zx::sec(5));
  DynamicNonPlatform non_platform;

  AnnotationManager manager(dispatcher(),
                            {
                                "annotation1",
                                "annotation2",
                                "num_calls",
                                "annotation3",
                                "annotation4",
                            },
                            static_annotations, &non_platform, {}, {&three_second_static},
                            {&five_second_dynamic});
  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(0))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopUntilIdle();
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "1"),
                                 MakePair("annotation3", Error::kTimeout),
                                 MakePair("annotation4", Error::kTimeout),
                             }));
  }

  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(3))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopFor(zx::sec(3));
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "2"),
                                 MakePair("annotation3", "value3"),
                                 MakePair("annotation4", Error::kTimeout),
                             }));
  }

  {
    Annotations annotations;

    executor.schedule_task(
        manager.GetAll(zx::sec(5))
            .and_then([&annotations](Annotations& result) { annotations = std::move(result); })
            .or_else([]() { FX_LOGS(FATAL) << "Unreachable error reached"; }));

    RunLoopFor(zx::sec(5));
    EXPECT_THAT(annotations, UnorderedElementsAreArray({
                                 MakePair("annotation1", "value1"),
                                 MakePair("annotation2", Error::kMissingValue),
                                 MakePair("num_calls", "3"),
                                 MakePair("annotation3", "value3"),
                                 MakePair("annotation4", "call3"),
                             }));
  }
}

}  // namespace
}  // namespace forensics::feedback
