// Copyright (c) 2012 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 "extensions/browser/api/idle/idle_api.h"

#include <limits.h>

#include <memory>
#include <string>

#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "extensions/browser/api/idle/idle_api_constants.h"
#include "extensions/browser/api/idle/idle_manager.h"
#include "extensions/browser/api/idle/idle_manager_factory.h"
#include "extensions/browser/api_unittest.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/api/idle.h"
#include "extensions/common/extension.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;

namespace idle = extensions::api::idle;

namespace extensions {

namespace {

class MockEventDelegate : public IdleManager::EventDelegate {
 public:
  MockEventDelegate() {}
  virtual ~MockEventDelegate() {}
  MOCK_METHOD2(OnStateChanged, void(const std::string&, ui::IdleState));
  virtual void RegisterObserver(EventRouter::Observer* observer) {}
  virtual void UnregisterObserver(EventRouter::Observer* observer) {}
};

class TestIdleProvider : public IdleManager::IdleTimeProvider {
 public:
  TestIdleProvider();
  ~TestIdleProvider() override;
  void CalculateIdleState(int idle_threshold, ui::IdleCallback notify) override;
  void CalculateIdleTime(ui::IdleTimeCallback notify) override;
  bool CheckIdleStateIsLocked() override;

  void set_idle_time(int idle_time);
  void set_locked(bool locked);

 private:
  int idle_time_;
  bool locked_;
};

TestIdleProvider::TestIdleProvider() : idle_time_(0), locked_(false) {
}

TestIdleProvider::~TestIdleProvider() {
}

void TestIdleProvider::CalculateIdleState(int idle_threshold,
                                          ui::IdleCallback notify) {
  if (locked_) {
    notify.Run(ui::IDLE_STATE_LOCKED);
  } else {
    if (idle_time_ >= idle_threshold) {
      notify.Run(ui::IDLE_STATE_IDLE);
    } else {
      notify.Run(ui::IDLE_STATE_ACTIVE);
    }
  }
}

void TestIdleProvider::CalculateIdleTime(ui::IdleTimeCallback notify) {
  notify.Run(idle_time_);
}

bool TestIdleProvider::CheckIdleStateIsLocked() {
  return locked_;
}

void TestIdleProvider::set_idle_time(int idle_time) {
  idle_time_ = idle_time;
}

void TestIdleProvider::set_locked(bool locked) {
  locked_ = locked;
}

class ScopedListen {
 public:
  ScopedListen(IdleManager* idle_manager, const std::string& extension_id);
  ~ScopedListen();

 private:
  IdleManager* idle_manager_;
  const std::string extension_id_;
};

ScopedListen::ScopedListen(IdleManager* idle_manager,
                           const std::string& extension_id)
    : idle_manager_(idle_manager), extension_id_(extension_id) {
  const EventListenerInfo details(idle::OnStateChanged::kEventName,
                                  extension_id_, GURL(), NULL);
  idle_manager_->OnListenerAdded(details);
}

ScopedListen::~ScopedListen() {
  const EventListenerInfo details(idle::OnStateChanged::kEventName,
                                  extension_id_, GURL(), NULL);
  idle_manager_->OnListenerRemoved(details);
}

std::unique_ptr<KeyedService> IdleManagerTestFactory(
    content::BrowserContext* context) {
  return base::MakeUnique<IdleManager>(context);
}

}  // namespace

class IdleTest : public ApiUnitTest {
 public:
  void SetUp() override;

 protected:
  IdleManager* idle_manager_;
  TestIdleProvider* idle_provider_;
  testing::StrictMock<MockEventDelegate>* event_delegate_;
};

void IdleTest::SetUp() {
  ApiUnitTest::SetUp();

  IdleManagerFactory::GetInstance()->SetTestingFactory(browser_context(),
                                                       &IdleManagerTestFactory);
  idle_manager_ = IdleManagerFactory::GetForBrowserContext(browser_context());

  idle_provider_ = new TestIdleProvider();
  idle_manager_->SetIdleTimeProviderForTest(
      std::unique_ptr<IdleManager::IdleTimeProvider>(idle_provider_));
  event_delegate_ = new testing::StrictMock<MockEventDelegate>();
  idle_manager_->SetEventDelegateForTest(
      std::unique_ptr<IdleManager::EventDelegate>(event_delegate_));
  idle_manager_->Init();
}

// Verifies that "locked" takes priority over "active".
TEST_F(IdleTest, QueryLockedActive) {
  idle_provider_->set_locked(true);
  idle_provider_->set_idle_time(0);

  std::unique_ptr<base::Value> result(
      RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));

  std::string idle_state;
  ASSERT_TRUE(result->GetAsString(&idle_state));
  EXPECT_EQ("locked", idle_state);
}

// Verifies that "locked" takes priority over "idle".
TEST_F(IdleTest, QueryLockedIdle) {
  idle_provider_->set_locked(true);
  idle_provider_->set_idle_time(INT_MAX);

  std::unique_ptr<base::Value> result(
      RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));

  std::string idle_state;
  ASSERT_TRUE(result->GetAsString(&idle_state));
  EXPECT_EQ("locked", idle_state);
}

// Verifies that any amount of idle time less than the detection interval
// translates to a state of "active".
TEST_F(IdleTest, QueryActive) {
  idle_provider_->set_locked(false);

  for (int time = 0; time < 60; ++time) {
    SCOPED_TRACE(time);
    idle_provider_->set_idle_time(time);

    std::unique_ptr<base::Value> result(
        RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));

    std::string idle_state;
    ASSERT_TRUE(result->GetAsString(&idle_state));
    EXPECT_EQ("active", idle_state);
  }
}

// Verifies that an idle time >= the detection interval returns the "idle"
// state.
TEST_F(IdleTest, QueryIdle) {
  idle_provider_->set_locked(false);

  for (int time = 80; time >= 60; --time) {
    SCOPED_TRACE(time);
    idle_provider_->set_idle_time(time);

    std::unique_ptr<base::Value> result(
        RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));

    std::string idle_state;
    ASSERT_TRUE(result->GetAsString(&idle_state));
    EXPECT_EQ("idle", idle_state);
  }
}

// Verifies that requesting a detection interval < 15 has the same effect as
// passing in 15.
TEST_F(IdleTest, QueryMinThreshold) {
  idle_provider_->set_locked(false);

  for (int threshold = 0; threshold < 20; ++threshold) {
    for (int time = 10; time < 60; ++time) {
      SCOPED_TRACE(threshold);
      SCOPED_TRACE(time);
      idle_provider_->set_idle_time(time);

      std::string args = "[" + base::IntToString(threshold) + "]";
      std::unique_ptr<base::Value> result(
          RunFunctionAndReturnValue(new IdleQueryStateFunction(), args));

      std::string idle_state;
      ASSERT_TRUE(result->GetAsString(&idle_state));

      int real_threshold = (threshold < 15) ? 15 : threshold;
      const char* expected = (time < real_threshold) ? "active" : "idle";
      EXPECT_EQ(expected, idle_state);
    }
  }
}

// Verifies that passing in a detection interval > 4 hours has the same effect
// as passing in 4 hours.
TEST_F(IdleTest, QueryMaxThreshold) {
  idle_provider_->set_locked(false);

  const int kFourHoursInSeconds = 4 * 60 * 60;

  for (int threshold = kFourHoursInSeconds - 20;
       threshold < (kFourHoursInSeconds + 20); ++threshold) {
    for (int time = kFourHoursInSeconds - 30; time < kFourHoursInSeconds + 30;
         ++time) {
      SCOPED_TRACE(threshold);
      SCOPED_TRACE(time);
      idle_provider_->set_idle_time(time);

      std::string args = "[" + base::IntToString(threshold) + "]";
      std::unique_ptr<base::Value> result(
          RunFunctionAndReturnValue(new IdleQueryStateFunction(), args));

      std::string idle_state;
      ASSERT_TRUE(result->GetAsString(&idle_state));

      int real_threshold =
          (threshold > kFourHoursInSeconds) ? kFourHoursInSeconds : threshold;
      const char* expected = (time < real_threshold) ? "active" : "idle";
      EXPECT_EQ(expected, idle_state);
    }
  }
}

// Verifies that transitioning from an active to idle state fires an "idle"
// OnStateChanged event.
TEST_F(IdleTest, ActiveToIdle) {
  ScopedListen listen_test(idle_manager_, "test");

  idle_provider_->set_locked(false);

  for (int time = 0; time < 60; ++time) {
    SCOPED_TRACE(time);
    idle_provider_->set_idle_time(time);

    idle_manager_->UpdateIdleState();
  }

  idle_provider_->set_idle_time(60);

  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
  testing::Mock::VerifyAndClearExpectations(event_delegate_);

  for (int time = 61; time < 75; ++time) {
    SCOPED_TRACE(time);
    idle_provider_->set_idle_time(time);
    idle_manager_->UpdateIdleState();
  }
}

// Verifies that locking an active system generates a "locked" event.
TEST_F(IdleTest, ActiveToLocked) {
  ScopedListen listen_test(idle_manager_, "test");

  idle_provider_->set_locked(true);
  idle_provider_->set_idle_time(5);

  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_LOCKED));
  idle_manager_->UpdateIdleState();
}

// Verifies that transitioning from an idle to active state generates an
// "active" event.
TEST_F(IdleTest, IdleToActive) {
  ScopedListen listen_test(idle_manager_, "test");

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(75);
  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
  testing::Mock::VerifyAndClearExpectations(event_delegate_);

  idle_provider_->set_idle_time(0);
  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_ACTIVE));
  idle_manager_->UpdateIdleState();
}

// Verifies that locking an idle system generates a "locked" event.
TEST_F(IdleTest, IdleToLocked) {
  ScopedListen listen_test(idle_manager_, "test");

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(75);

  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
  testing::Mock::VerifyAndClearExpectations(event_delegate_);

  idle_provider_->set_locked(true);
  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_LOCKED));
  idle_manager_->UpdateIdleState();
}

// Verifies that unlocking an active system generates an "active" event.
TEST_F(IdleTest, LockedToActive) {
  ScopedListen listen_test(idle_manager_, "test");

  idle_provider_->set_locked(true);
  idle_provider_->set_idle_time(0);

  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_LOCKED));
  idle_manager_->UpdateIdleState();

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(5);
  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_ACTIVE));
  idle_manager_->UpdateIdleState();
}

// Verifies that unlocking an inactive system generates an "idle" event.
TEST_F(IdleTest, LockedToIdle) {
  ScopedListen listen_test(idle_manager_, "test");

  idle_provider_->set_locked(true);
  idle_provider_->set_idle_time(75);
  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_LOCKED));
  idle_manager_->UpdateIdleState();
  testing::Mock::VerifyAndClearExpectations(event_delegate_);

  idle_provider_->set_locked(false);
  EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
}

// Verifies that events are routed to extensions that have one or more listeners
// in scope.
TEST_F(IdleTest, MultipleExtensions) {
  ScopedListen listen_1(idle_manager_, "1");
  ScopedListen listen_2(idle_manager_, "2");

  idle_provider_->set_locked(true);
  EXPECT_CALL(*event_delegate_, OnStateChanged("1", ui::IDLE_STATE_LOCKED));
  EXPECT_CALL(*event_delegate_, OnStateChanged("2", ui::IDLE_STATE_LOCKED));
  idle_manager_->UpdateIdleState();
  testing::Mock::VerifyAndClearExpectations(event_delegate_);

  {
    ScopedListen listen_2prime(idle_manager_, "2");
    ScopedListen listen_3(idle_manager_, "3");
    idle_provider_->set_locked(false);
    EXPECT_CALL(*event_delegate_, OnStateChanged("1", ui::IDLE_STATE_ACTIVE));
    EXPECT_CALL(*event_delegate_, OnStateChanged("2", ui::IDLE_STATE_ACTIVE));
    EXPECT_CALL(*event_delegate_, OnStateChanged("3", ui::IDLE_STATE_ACTIVE));
    idle_manager_->UpdateIdleState();
    testing::Mock::VerifyAndClearExpectations(event_delegate_);
  }

  idle_provider_->set_locked(true);
  EXPECT_CALL(*event_delegate_, OnStateChanged("1", ui::IDLE_STATE_LOCKED));
  EXPECT_CALL(*event_delegate_, OnStateChanged("2", ui::IDLE_STATE_LOCKED));
  idle_manager_->UpdateIdleState();
}

// Verifies that setDetectionInterval changes the detection interval from the
// default of 60 seconds, and that the call only affects a single extension's
// IdleMonitor.
TEST_F(IdleTest, SetDetectionInterval) {
  ScopedListen listen_default(idle_manager_, "default");
  ScopedListen listen_extension(idle_manager_, extension()->id());

  std::unique_ptr<base::Value> result45(RunFunctionAndReturnValue(
      new IdleSetDetectionIntervalFunction(), "[45]"));

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(44);
  idle_manager_->UpdateIdleState();

  idle_provider_->set_idle_time(45);
  EXPECT_CALL(*event_delegate_,
              OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
  // Verify that the expectation has been fulfilled before incrementing the
  // time again.
  testing::Mock::VerifyAndClearExpectations(event_delegate_);

  idle_provider_->set_idle_time(60);
  EXPECT_CALL(*event_delegate_, OnStateChanged("default", ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
}

// Verifies that setting the detection interval before creating the listener
// works correctly.
TEST_F(IdleTest, SetDetectionIntervalBeforeListener) {
  std::unique_ptr<base::Value> result45(RunFunctionAndReturnValue(
      new IdleSetDetectionIntervalFunction(), "[45]"));

  ScopedListen listen_extension(idle_manager_, extension()->id());

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(44);
  idle_manager_->UpdateIdleState();

  idle_provider_->set_idle_time(45);
  EXPECT_CALL(*event_delegate_,
              OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
}

// Verifies that setting a detection interval above the maximum value results
// in an interval of 4 hours.
TEST_F(IdleTest, SetDetectionIntervalMaximum) {
  ScopedListen listen_extension(idle_manager_, extension()->id());

  std::unique_ptr<base::Value> result(
      RunFunctionAndReturnValue(new IdleSetDetectionIntervalFunction(),
                                "[18000]"));  // five hours in seconds

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(4 * 60 * 60 - 1);
  idle_manager_->UpdateIdleState();

  idle_provider_->set_idle_time(4 * 60 * 60);
  EXPECT_CALL(*event_delegate_,
              OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
}

// Verifies that setting a detection interval below the minimum value results
// in an interval of 15 seconds.
TEST_F(IdleTest, SetDetectionIntervalMinimum) {
  ScopedListen listen_extension(idle_manager_, extension()->id());

  std::unique_ptr<base::Value> result(RunFunctionAndReturnValue(
      new IdleSetDetectionIntervalFunction(), "[10]"));

  idle_provider_->set_locked(false);
  idle_provider_->set_idle_time(14);
  idle_manager_->UpdateIdleState();

  idle_provider_->set_idle_time(15);
  EXPECT_CALL(*event_delegate_,
              OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE));
  idle_manager_->UpdateIdleState();
}

// Verifies that an extension's detection interval is discarded when it unloads.
TEST_F(IdleTest, UnloadCleanup) {
  {
    ScopedListen listen(idle_manager_, extension()->id());

    std::unique_ptr<base::Value> result45(RunFunctionAndReturnValue(
        new IdleSetDetectionIntervalFunction(), "[15]"));
  }

  // Listener count dropping to zero does not reset threshold.

  {
    ScopedListen listen(idle_manager_, extension()->id());
    idle_provider_->set_idle_time(16);
    EXPECT_CALL(*event_delegate_,
                OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE));
    idle_manager_->UpdateIdleState();
    testing::Mock::VerifyAndClearExpectations(event_delegate_);
  }

  // Threshold will reset after unload (and listen count == 0)
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
  registry->TriggerOnUnloaded(extension(),
                              UnloadedExtensionInfo::REASON_UNINSTALL);

  {
    ScopedListen listen(idle_manager_, extension()->id());
    idle_manager_->UpdateIdleState();
    testing::Mock::VerifyAndClearExpectations(event_delegate_);

    idle_provider_->set_idle_time(61);
    EXPECT_CALL(*event_delegate_,
                OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE));
    idle_manager_->UpdateIdleState();
  }
}

// Verifies that unloading an extension with no listeners or threshold works.
TEST_F(IdleTest, UnloadOnly) {
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
  registry->TriggerOnUnloaded(extension(),
                              UnloadedExtensionInfo::REASON_UNINSTALL);
}

// Verifies that its ok for the unload notification to happen before all the
// listener removals.
TEST_F(IdleTest, UnloadWhileListening) {
  ScopedListen listen(idle_manager_, extension()->id());
  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
  registry->TriggerOnUnloaded(extension(),
                              UnloadedExtensionInfo::REASON_UNINSTALL);
}

// Verifies that re-adding a listener after a state change doesn't immediately
// fire a change event. Regression test for http://crbug.com/366580.
TEST_F(IdleTest, ReAddListener) {
  idle_provider_->set_locked(false);

  {
    // Fire idle event.
    ScopedListen listen(idle_manager_, "test");
    idle_provider_->set_idle_time(60);
    EXPECT_CALL(*event_delegate_, OnStateChanged("test", ui::IDLE_STATE_IDLE));
    idle_manager_->UpdateIdleState();
    testing::Mock::VerifyAndClearExpectations(event_delegate_);
  }

  // Trigger active.
  idle_provider_->set_idle_time(0);
  idle_manager_->UpdateIdleState();

  {
    // Nothing should have fired, the listener wasn't added until afterward.
    ScopedListen listen(idle_manager_, "test");
    idle_manager_->UpdateIdleState();
    testing::Mock::VerifyAndClearExpectations(event_delegate_);
  }
}

}  // namespace extensions
