// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: jmarantz@google.com (Joshua Marantz)

#include "pagespeed/kernel/thread/mock_scheduler.h"

#include "pagespeed/kernel/base/abstract_mutex.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/function.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/thread/scheduler.h"
#include "pagespeed/kernel/util/platform.h"

namespace net_instaweb {

namespace {

// Make the simulated times be very long just to show that we are in
// mock time and don't need to wait a century for this test to finish.
const int64 kDelayMs = 50 * Timer::kYearMs;
const int64 kWaitMs = 100 * Timer::kYearMs;

class TestAlarm : public Function {
 public:
  TestAlarm() {}
  virtual void Run() { }
};

// This is an alarm implementation which adds new alarms and optionally advances
// time in its callback.
class ChainedAlarm : public Function {
 public:
  // Constructs a chained alarm that will run *count times with 100ms delay
  // between each alarm.  If 'advance' is set, it will advance time forward
  // by 100ms on each call so that the chain unwinds itself.
  ChainedAlarm(MockScheduler* scheduler, int* count, bool advance)
      : scheduler_(scheduler),
        count_(count),
        advance_(advance) {}

  virtual void Run() {
    if (--*count_ > 0) {
      int64 next_time_us = scheduler_->timer()->NowUs();
      scheduler_->AddAlarmAtUs(next_time_us,
                               new ChainedAlarm(scheduler_, count_, advance_));
      if (advance_) {
        scheduler_->AdvanceTimeUs(100);
      }
    }
  }

 private:
  MockScheduler* scheduler_;
  int* count_;
  bool advance_;

  DISALLOW_COPY_AND_ASSIGN(ChainedAlarm);
};

}  // namespace

class MockSchedulerTest : public testing::Test {
 protected:
  MockSchedulerTest()
      : thread_system_(Platform::CreateThreadSystem()),
        timer_(thread_system_->NewMutex(), 0),
        scheduler_(new MockScheduler(thread_system_.get(), &timer_)),
        was_run_(false),
        was_cancelled_(false) {}

  Scheduler::Alarm* AddTask(int64 wakeup_time_us, char c) {
    Function* append_char = MakeFunction<GoogleString, char>(
        &string_, &GoogleString::push_back, c);
    return scheduler_->AddAlarmAtUs(wakeup_time_us, append_char);
  }

  void Run() {
    was_run_ = true;
  }

  void Cancel() {
    was_cancelled_ = true;
  }

  Scheduler::Alarm* AddRunCancelAlarmUs(int64 wakeup_time_us) {
    return scheduler_->AddAlarmAtUs(wakeup_time_us, MakeFunction(
        this, &MockSchedulerTest::Run, &MockSchedulerTest::Cancel));
  }

  void AdvanceTimeMs(int64 interval_ms) {
    scheduler_->AdvanceTimeMs(interval_ms);
  }

  void AdvanceTimeUs(int64 interval_us) {
    scheduler_->AdvanceTimeUs(interval_us);
  }

 protected:
  scoped_ptr<ThreadSystem> thread_system_;
  MockTimer timer_;
  scoped_ptr<MockScheduler> scheduler_;
  GoogleString string_;
  bool was_run_;
  bool was_cancelled_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MockSchedulerTest);
};

TEST_F(MockSchedulerTest, ScheduleOrdering) {
  AddTask(1, '1');
  AddTask(3, '3');
  AddTask(2, '2');
  AdvanceTimeMs(3);  // runs all 3 tasks
  EXPECT_EQ("123", string_);
}

TEST_F(MockSchedulerTest, AdvancePastLastScheduledEvent) {
  AddTask(1, '1');
  AdvanceTimeMs(3);  // runs 1 ask, but moves time 2ms further.
  EXPECT_EQ("1", string_);
  EXPECT_EQ(3, timer_.NowMs());
}

TEST_F(MockSchedulerTest, SchedulePartial) {
  AddTask(5, '5');
  AddTask(5, '6');  // same wakeup time, but order is preserved.
  AddTask(6, '7');
  AddTask(3, '3');
  AddTask(2, '2');
  AddTask(4, '4');
  AddTask(1, '1');
  AdvanceTimeUs(3);  // runs first 3 tasks
  EXPECT_EQ("123", string_);
  string_.clear();
  AdvanceTimeUs(3);  // runs next 4 tasks
  EXPECT_EQ("4567", string_);
}

TEST_F(MockSchedulerTest, Cancellation) {
  AddTask(1, '1');
  Scheduler::Alarm* alarm_to_cancel = AddTask(3, '3');
  AddTask(2, '2');
  AddTask(4, '4');
  {
    ScopedMutex lock(scheduler_->mutex());
    scheduler_->CancelAlarm(alarm_to_cancel);
  }
  AdvanceTimeUs(4);  // runs the 3 tasks not canceled.
  EXPECT_EQ("124", string_);
}

// Verifies that we can add a new alarm from an Alarm::Run() method.
TEST_F(MockSchedulerTest, ChainedAlarms) {
  int count = 10;
  scheduler_->AddAlarmAtUs(
      100, new ChainedAlarm(scheduler_.get(), &count, false));
  AdvanceTimeUs(1000);
  EXPECT_EQ(0, count);
}

// Verifies that we can advance time from an Alarm::Run() method.
TEST_F(MockSchedulerTest, AdvanceFromRun) {
  int count = 10;
  scheduler_->AddAlarmAtUs(
      100, new ChainedAlarm(scheduler_.get(), &count, true));
  AdvanceTimeUs(100);
  EXPECT_EQ(0, count);
}

TEST_F(MockSchedulerTest, RunNotCancelled) {
  // First, let the alarm run normally.
  AddRunCancelAlarmUs(100);
  AdvanceTimeUs(200);
  EXPECT_TRUE(was_run_);
  EXPECT_FALSE(was_cancelled_);
}

TEST_F(MockSchedulerTest, CancelledExplicitly) {
  // Next cancel the alarm explicitly before it runs.
  Scheduler::Alarm* alarm = AddRunCancelAlarmUs(500);
  {
    ScopedMutex lock(scheduler_->mutex());
    scheduler_->CancelAlarm(alarm);
  }
  EXPECT_FALSE(was_run_);
  EXPECT_TRUE(was_cancelled_);
}

#if SCHEDULER_CANCEL_OUTSTANDING_ALARMS_ON_DESTRUCTION
// Note that this test will not only fail without canceling the alarms on
// destruction, it will also leak the alarms.
TEST_F(MockSchedulerTest, CancelledDueToMockSchedulerDestruction) {
  // Finally, let the alarm be implicitly cancelled by deleting the scheduler.
  AddRunCancelAlarmUs(500);
  scheduler_.reset(NULL);
  EXPECT_FALSE(was_run_);
  EXPECT_TRUE(was_cancelled_);
}
#endif

TEST_F(MockSchedulerTest, WakeupOnAdvancementOfSimulatedTime) {
  scheduler_->AddAlarmAtUs(Timer::kMsUs * kDelayMs, new TestAlarm());
  {
    AdvanceTimeMs(kWaitMs);

    // The idle-callback will get run after 50 years, but TimedWait
    // won't actually return until the full 100 years has passed.
    EXPECT_EQ(kWaitMs, timer_.NowMs());
  }
}

}  // namespace net_instaweb
