/*
 *  Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "api/environment/environment.h"

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials_view.h"
#include "api/rtc_event_log/rtc_event.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/units/timestamp.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::NotNull;
using ::testing::Ref;

class FakeEvent : public RtcEvent {
 public:
  Type GetType() const override { return RtcEvent::Type::FakeEvent; }
  bool IsConfigEvent() const override { return false; }
};

class FakeFieldTrials : public FieldTrialsView {
 public:
  explicit FakeFieldTrials(absl::AnyInvocable<void() &&> on_destroyed = nullptr)
      : on_destroyed_(std::move(on_destroyed)) {}
  ~FakeFieldTrials() override {
    if (on_destroyed_ != nullptr) {
      std::move(on_destroyed_)();
    }
  }

  std::string Lookup(absl::string_view key) const override { return "fake"; }

 private:
  absl::AnyInvocable<void() &&> on_destroyed_;
};

class FakeTaskQueueFactory : public TaskQueueFactory {
 public:
  explicit FakeTaskQueueFactory(
      absl::AnyInvocable<void() &&> on_destroyed = nullptr)
      : on_destroyed_(std::move(on_destroyed)) {}
  ~FakeTaskQueueFactory() override {
    if (on_destroyed_ != nullptr) {
      std::move(on_destroyed_)();
    }
  }

  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
      absl::string_view name,
      Priority priority) const override {
    return nullptr;
  }

 private:
  absl::AnyInvocable<void() &&> on_destroyed_;
};

TEST(EnvironmentTest, DefaultEnvironmentHasAllUtilities) {
  Environment env = EnvironmentFactory().Create();

  // Try to use each utility, expect no crashes.
  env.clock().CurrentTime();
  EXPECT_THAT(env.task_queue_factory().CreateTaskQueue(
                  "test", TaskQueueFactory::Priority::NORMAL),
              NotNull());
  env.event_log().Log(std::make_unique<FakeEvent>());
  env.field_trials().Lookup("WebRTC-Debugging-RtpDump");
}

TEST(EnvironmentTest, UsesProvidedUtilitiesWithOwnership) {
  auto owned_field_trials = std::make_unique<FakeFieldTrials>();
  auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>();
  auto owned_clock = std::make_unique<SimulatedClock>(Timestamp::Zero());
  auto owned_event_log = std::make_unique<RtcEventLogNull>();

  FieldTrialsView& field_trials = *owned_field_trials;
  TaskQueueFactory& task_queue_factory = *owned_task_queue_factory;
  Clock& clock = *owned_clock;
  RtcEventLog& event_log = *owned_event_log;

  Environment env = CreateEnvironment(
      std::move(owned_field_trials), std::move(owned_clock),
      std::move(owned_task_queue_factory), std::move(owned_event_log));

  EXPECT_THAT(env.field_trials(), Ref(field_trials));
  EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory));
  EXPECT_THAT(env.clock(), Ref(clock));
  EXPECT_THAT(env.event_log(), Ref(event_log));
}

TEST(EnvironmentTest, UsesProvidedUtilitiesWithoutOwnership) {
  FakeFieldTrials field_trials;
  FakeTaskQueueFactory task_queue_factory;
  SimulatedClock clock(Timestamp::Zero());
  RtcEventLogNull event_log;

  Environment env =
      CreateEnvironment(&field_trials, &clock, &task_queue_factory, &event_log);

  EXPECT_THAT(env.field_trials(), Ref(field_trials));
  EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory));
  EXPECT_THAT(env.clock(), Ref(clock));
  EXPECT_THAT(env.event_log(), Ref(event_log));
}

TEST(EnvironmentTest, UsesLastProvidedUtility) {
  auto owned_field_trials1 = std::make_unique<FakeFieldTrials>();
  auto owned_field_trials2 = std::make_unique<FakeFieldTrials>();
  FieldTrialsView& field_trials2 = *owned_field_trials2;

  Environment env = CreateEnvironment(std::move(owned_field_trials1),
                                      std::move(owned_field_trials2));

  EXPECT_THAT(env.field_trials(), Ref(field_trials2));
}

// Utilities can be provided from different sources, and when some source
// choose not to provide an utility, it is usually expressed with nullptr.
// When utility is not provided, it is natural to use previously set one.
// E.g. Both PeerConnectionFactoryDependencies and PeerConnectionDependencies
// provide field trials. When PeerConnectionDependencies::trials == nullptr,
// then trials from the PeerConnectionFactoryDependencies should be used.
// With nullptr accepted and ignored this can be expressed by
// `Environemt env = CreateEnvironment(pcf_deps.trials, pc_deps.trials);`
// That would use pc_deps.trials when not nullptr, pcf_deps.trials when
// pc_deps.trials is nullptr, but pcf_deps.trials is not, and default field
// trials when both are nullptr.
TEST(EnvironmentTest, IgnoresProvidedNullptrUtility) {
  auto owned_field_trials = std::make_unique<FakeFieldTrials>();
  std::unique_ptr<FieldTrialsView> null_field_trials = nullptr;
  FieldTrialsView& field_trials = *owned_field_trials;

  Environment env = CreateEnvironment(std::move(owned_field_trials),
                                      std::move(null_field_trials));

  EXPECT_THAT(env.field_trials(), Ref(field_trials));
}

TEST(EnvironmentTest, KeepsUtilityAliveWhileEnvironmentIsAlive) {
  bool utility_destroyed = false;
  auto field_trials = std::make_unique<FakeFieldTrials>(
      /*on_destroyed=*/[&] { utility_destroyed = true; });

  // Wrap Environment into optional to have explicit control when it is deleted.
  std::optional<Environment> env = CreateEnvironment(std::move(field_trials));

  EXPECT_FALSE(utility_destroyed);
  env = std::nullopt;
  EXPECT_TRUE(utility_destroyed);
}

TEST(EnvironmentTest, KeepsUtilityAliveWhileCopyOfEnvironmentIsAlive) {
  bool utility_destroyed = false;
  auto field_trials = std::make_unique<FakeFieldTrials>(
      /*on_destroyed=*/[&] { utility_destroyed = true; });

  std::optional<Environment> env1 = CreateEnvironment(std::move(field_trials));
  std::optional<Environment> env2 = env1;

  EXPECT_FALSE(utility_destroyed);
  env1 = std::nullopt;
  EXPECT_FALSE(utility_destroyed);
  env2 = std::nullopt;
  EXPECT_TRUE(utility_destroyed);
}

TEST(EnvironmentTest, FactoryCanBeReusedToCreateDifferentEnvironments) {
  auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>();
  auto owned_field_trials1 = std::make_unique<FakeFieldTrials>();
  auto owned_field_trials2 = std::make_unique<FakeFieldTrials>();
  TaskQueueFactory& task_queue_factory = *owned_task_queue_factory;
  FieldTrialsView& field_trials1 = *owned_field_trials1;
  FieldTrialsView& field_trials2 = *owned_field_trials2;

  EnvironmentFactory factory;
  factory.Set(std::move(owned_task_queue_factory));
  factory.Set(std::move(owned_field_trials1));
  Environment env1 = factory.Create();
  factory.Set(std::move(owned_field_trials2));
  Environment env2 = factory.Create();

  // Environments share the same custom task queue factory.
  EXPECT_THAT(env1.task_queue_factory(), Ref(task_queue_factory));
  EXPECT_THAT(env2.task_queue_factory(), Ref(task_queue_factory));

  // Environments have different field trials.
  EXPECT_THAT(env1.field_trials(), Ref(field_trials1));
  EXPECT_THAT(env2.field_trials(), Ref(field_trials2));
}

TEST(EnvironmentTest, FactoryCanCreateNewEnvironmentFromExistingOne) {
  Environment env1 =
      CreateEnvironment(std::make_unique<FakeTaskQueueFactory>());
  EnvironmentFactory factory(env1);
  factory.Set(std::make_unique<FakeFieldTrials>());
  Environment env2 = factory.Create();

  // Environments share the same default clock.
  EXPECT_THAT(env2.clock(), Ref(env1.clock()));

  // Environments share the same custom task queue factory.
  EXPECT_THAT(env2.task_queue_factory(), Ref(env1.task_queue_factory()));

  // Environments have different field trials.
  EXPECT_THAT(env2.field_trials(), Not(Ref(env1.field_trials())));
}

TEST(EnvironmentTest, KeepsOwnershipsWhenCreateNewEnvironmentFromExistingOne) {
  bool utility1_destroyed = false;
  bool utility2_destroyed = false;
  std::optional<Environment> env1 =
      CreateEnvironment(std::make_unique<FakeTaskQueueFactory>(
          /*on_destroyed=*/[&] { utility1_destroyed = true; }));

  std::optional<EnvironmentFactory> factory = EnvironmentFactory(*env1);

  // Destroy env1, check utility1 it was using is still alive.
  env1 = std::nullopt;
  EXPECT_FALSE(utility1_destroyed);

  factory->Set(std::make_unique<FakeFieldTrials>(
      /*on_destroyed=*/[&] { utility2_destroyed = true; }));
  std::optional<Environment> env2 = factory->Create();

  // Destroy the factory, check all utilities used by env2 are alive.
  factory = std::nullopt;
  EXPECT_FALSE(utility1_destroyed);
  EXPECT_FALSE(utility2_destroyed);

  // Once last Environment object is deleted, utilties should be deleted too.
  env2 = std::nullopt;
  EXPECT_TRUE(utility1_destroyed);
  EXPECT_TRUE(utility2_destroyed);
}

TEST(EnvironmentTest, DestroysUtilitiesInReverseProvidedOrder) {
  std::vector<std::string> destroyed;
  auto field_trials = std::make_unique<FakeFieldTrials>(
      /*on_destroyed=*/[&] { destroyed.push_back("field_trials"); });
  auto task_queue_factory = std::make_unique<FakeTaskQueueFactory>(
      /*on_destroyed=*/[&] { destroyed.push_back("task_queue_factory"); });

  std::optional<Environment> env =
      CreateEnvironment(std::move(field_trials), std::move(task_queue_factory));

  ASSERT_THAT(destroyed, IsEmpty());
  env = std::nullopt;
  EXPECT_THAT(destroyed, ElementsAre("task_queue_factory", "field_trials"));
}

}  // namespace
}  // namespace webrtc
