// Copyright 2013 The Chromium 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 "quic/core/quic_alarm.h"

#include "quic/core/quic_connection_context.h"
#include "quic/platform/api/quic_expect_bug.h"
#include "quic/platform/api/quic_test.h"

using testing::ElementsAre;
using testing::Invoke;
using testing::Return;

namespace quic {
namespace test {
namespace {

class TraceCollector : public QuicConnectionTracer {
 public:
  ~TraceCollector() override = default;

  void PrintLiteral(const char* literal) override { trace_.push_back(literal); }

  void PrintString(absl::string_view s) override {
    trace_.push_back(std::string(s));
  }

  const std::vector<std::string>& trace() const { return trace_; }

 private:
  std::vector<std::string> trace_;
};

class MockDelegate : public QuicAlarm::Delegate {
 public:
  MOCK_METHOD(QuicConnectionContext*, GetConnectionContext, (), (override));
  MOCK_METHOD(void, OnAlarm, (), (override));
};

class DestructiveDelegate : public QuicAlarm::DelegateWithoutContext {
 public:
  DestructiveDelegate() : alarm_(nullptr) {}

  void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; }

  void OnAlarm() override {
    QUICHE_DCHECK(alarm_);
    delete alarm_;
  }

 private:
  QuicAlarm* alarm_;
};

class TestAlarm : public QuicAlarm {
 public:
  explicit TestAlarm(QuicAlarm::Delegate* delegate)
      : QuicAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)) {}

  bool scheduled() const { return scheduled_; }

  void FireAlarm() {
    scheduled_ = false;
    Fire();
  }

 protected:
  void SetImpl() override {
    QUICHE_DCHECK(deadline().IsInitialized());
    scheduled_ = true;
  }

  void CancelImpl() override {
    QUICHE_DCHECK(!deadline().IsInitialized());
    scheduled_ = false;
  }

 private:
  bool scheduled_;
};

class DestructiveAlarm : public QuicAlarm {
 public:
  explicit DestructiveAlarm(DestructiveDelegate* delegate)
      : QuicAlarm(QuicArenaScopedPtr<DestructiveDelegate>(delegate)) {}

  void FireAlarm() { Fire(); }

 protected:
  void SetImpl() override {}

  void CancelImpl() override {}
};

class QuicAlarmTest : public QuicTest {
 public:
  QuicAlarmTest()
      : delegate_(new MockDelegate()),
        alarm_(delegate_),
        deadline_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(7)),
        deadline2_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(14)),
        new_deadline_(QuicTime::Zero()) {}

  void ResetAlarm() { alarm_.Set(new_deadline_); }

  MockDelegate* delegate_;  // not owned
  TestAlarm alarm_;
  QuicTime deadline_;
  QuicTime deadline2_;
  QuicTime new_deadline_;
};

TEST_F(QuicAlarmTest, IsSet) {
  EXPECT_FALSE(alarm_.IsSet());
}

TEST_F(QuicAlarmTest, Set) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);
  EXPECT_TRUE(alarm_.IsSet());
  EXPECT_TRUE(alarm_.scheduled());
  EXPECT_EQ(deadline, alarm_.deadline());
}

TEST_F(QuicAlarmTest, Cancel) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);
  alarm_.Cancel();
  EXPECT_FALSE(alarm_.IsSet());
  EXPECT_FALSE(alarm_.scheduled());
  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
}

TEST_F(QuicAlarmTest, PermanentCancel) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);
  alarm_.PermanentCancel();
  EXPECT_FALSE(alarm_.IsSet());
  EXPECT_FALSE(alarm_.scheduled());
  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());

  EXPECT_QUIC_BUG(alarm_.Set(deadline),
                  "Set called after alarm is permanently cancelled");
  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
  EXPECT_FALSE(alarm_.IsSet());
  EXPECT_FALSE(alarm_.scheduled());
  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());

  EXPECT_QUIC_BUG(alarm_.Update(deadline, QuicTime::Delta::Zero()),
                  "Update called after alarm is permanently cancelled");
  EXPECT_TRUE(alarm_.IsPermanentlyCancelled());
  EXPECT_FALSE(alarm_.IsSet());
  EXPECT_FALSE(alarm_.scheduled());
  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
}

TEST_F(QuicAlarmTest, Update) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);
  QuicTime new_deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(8);
  alarm_.Update(new_deadline, QuicTime::Delta::Zero());
  EXPECT_TRUE(alarm_.IsSet());
  EXPECT_TRUE(alarm_.scheduled());
  EXPECT_EQ(new_deadline, alarm_.deadline());
}

TEST_F(QuicAlarmTest, UpdateWithZero) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);
  alarm_.Update(QuicTime::Zero(), QuicTime::Delta::Zero());
  EXPECT_FALSE(alarm_.IsSet());
  EXPECT_FALSE(alarm_.scheduled());
  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
}

TEST_F(QuicAlarmTest, Fire) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);
  EXPECT_CALL(*delegate_, OnAlarm());
  alarm_.FireAlarm();
  EXPECT_FALSE(alarm_.IsSet());
  EXPECT_FALSE(alarm_.scheduled());
  EXPECT_EQ(QuicTime::Zero(), alarm_.deadline());
}

TEST_F(QuicAlarmTest, FireAndResetViaSet) {
  alarm_.Set(deadline_);
  new_deadline_ = deadline2_;
  EXPECT_CALL(*delegate_, OnAlarm())
      .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm));
  alarm_.FireAlarm();
  EXPECT_TRUE(alarm_.IsSet());
  EXPECT_TRUE(alarm_.scheduled());
  EXPECT_EQ(deadline2_, alarm_.deadline());
}

TEST_F(QuicAlarmTest, FireDestroysAlarm) {
  DestructiveDelegate* delegate(new DestructiveDelegate);
  DestructiveAlarm* alarm = new DestructiveAlarm(delegate);
  delegate->set_alarm(alarm);
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm->Set(deadline);
  // This should not crash, even though it will destroy alarm.
  alarm->FireAlarm();
}

TEST_F(QuicAlarmTest, NullAlarmContext) {
  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);

  if (GetQuicReloadableFlag(quic_restore_connection_context_in_alarms)) {
    EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(nullptr));
  }

  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
    QUIC_TRACELITERAL("Alarm fired.");
  }));
  alarm_.FireAlarm();
}

TEST_F(QuicAlarmTest, AlarmContextWithNullTracer) {
  QuicConnectionContext context;
  ASSERT_EQ(context.tracer, nullptr);

  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);

  if (GetQuicReloadableFlag(quic_restore_connection_context_in_alarms)) {
    EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
  }

  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
    QUIC_TRACELITERAL("Alarm fired.");
  }));
  alarm_.FireAlarm();
}

TEST_F(QuicAlarmTest, AlarmContextWithTracer) {
  QuicConnectionContext context;
  std::unique_ptr<TraceCollector> tracer = std::make_unique<TraceCollector>();
  const TraceCollector& tracer_ref = *tracer;
  context.tracer = std::move(tracer);

  QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7);
  alarm_.Set(deadline);

  if (GetQuicReloadableFlag(quic_restore_connection_context_in_alarms)) {
    EXPECT_CALL(*delegate_, GetConnectionContext()).WillOnce(Return(&context));
  }

  EXPECT_CALL(*delegate_, OnAlarm()).WillOnce(Invoke([] {
    QUIC_TRACELITERAL("Alarm fired.");
  }));

  // Since |context| is not installed in the current thread, the messages before
  // and after FireAlarm() should not be collected by |tracer|.
  QUIC_TRACELITERAL("Should not be collected before alarm.");
  alarm_.FireAlarm();
  QUIC_TRACELITERAL("Should not be collected after alarm.");

  if (GetQuicReloadableFlag(quic_restore_connection_context_in_alarms)) {
    EXPECT_THAT(tracer_ref.trace(), ElementsAre("Alarm fired."));
  } else {
    EXPECT_TRUE(tracer_ref.trace().empty());
  }
}

}  // namespace
}  // namespace test
}  // namespace quic
