/*
 *  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/environment/force_test_environment.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/create_test_environment.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;
using ::testing::Test;

class EnvironmentTest : public Test {
 private:
  AutoBypassTestEnvironmentCheck bypass_;
};

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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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_F(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"));
}

TEST_F(EnvironmentTest, CreateTestEnvironmentWorksWhenForced) {
  struct ScopedForce {
    ScopedForce() {
      old_value = IsForceTestEnvironmentEnabled();
      SetForceTestEnvironment(true);
    }
    ~ScopedForce() { SetForceTestEnvironment(old_value); }
    bool old_value;
  } force;

  Environment env = CreateTestEnvironment();
  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");
}

#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(EnvironmentDeathTest, CreateEnvironmentCrashesWhenForced) {
  EXPECT_DEATH(
      {
        SetForceTestEnvironment(true);
        CreateEnvironment();
      },
      "is not allowed in tests.");
}
#endif

}  // namespace
}  // namespace webrtc
