/*
 *  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";
  }

  std::unique_ptr<FieldTrialsView> CreateCopy() const override {
    return std::make_unique<FakeFieldTrials>([] {});
  }

 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::kNormal),
              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
