// Copyright 2014 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 "components/proximity_auth/proximity_auth_system.h"

#include "base/command_line.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/cryptauth/remote_device.h"
#include "components/proximity_auth/fake_lock_handler.h"
#include "components/proximity_auth/fake_remote_device_life_cycle.h"
#include "components/proximity_auth/logging/logging.h"
#include "components/proximity_auth/mock_proximity_auth_client.h"
#include "components/proximity_auth/proximity_auth_profile_pref_manager.h"
#include "components/proximity_auth/switches.h"
#include "components/proximity_auth/unlock_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using cryptauth::RemoteDevice;
using cryptauth::RemoteDeviceList;
using testing::AnyNumber;
using testing::AtLeast;
using testing::InSequence;
using testing::NiceMock;
using testing::NotNull;
using testing::Return;
using testing::SaveArg;
using testing::_;

namespace proximity_auth {

namespace {

const char kUser1[] = "user1";
const char kUser2[] = "user2";

const int64_t kLastPasswordEntryTimestampMs = 123456L;
const int64_t kTimestampBeforeReauthMs = 123457L;
const int64_t kTimestampAfterReauthMs = 123457890123L;

void CompareRemoteDeviceLists(const RemoteDeviceList& list1,
                              const RemoteDeviceList& list2) {
  ASSERT_EQ(list1.size(), list2.size());
  for (size_t i = 0; i < list1.size(); ++i) {
    RemoteDevice device1 = list1[i];
    RemoteDevice device2 = list2[i];
    EXPECT_EQ(device1.public_key, device2.public_key);
  }
}

// Creates a RemoteDevice object for |user_id| with |name|.
RemoteDevice CreateRemoteDevice(const std::string& user_id,
                                const std::string& name) {
  return RemoteDevice(user_id, name + "_pk", name, name + "_btaddr",
                      name + "_psk", true /* unlock_key */,
                      true /* supports_mobile_hotspot */,
                      0 /* last_update_time_millis */);
}

// Mock implementation of UnlockManager.
class MockUnlockManager : public UnlockManager {
 public:
  MockUnlockManager() {}
  ~MockUnlockManager() override {}
  MOCK_METHOD0(IsUnlockAllowed, bool());
  MOCK_METHOD1(SetRemoteDeviceLifeCycle, void(RemoteDeviceLifeCycle*));
  MOCK_METHOD0(OnLifeCycleStateChanged, void());
  MOCK_METHOD1(OnAuthAttempted, void(mojom::AuthType));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockUnlockManager);
};

// Mock implementation of ProximityAuthProfilePrefManager.
class MockProximityAuthPrefManager : public ProximityAuthProfilePrefManager {
 public:
  MockProximityAuthPrefManager() : ProximityAuthProfilePrefManager(nullptr) {}
  ~MockProximityAuthPrefManager() override {}
  MOCK_CONST_METHOD0(GetLastPasswordEntryTimestampMs, int64_t());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockProximityAuthPrefManager);
};

// Harness for ProximityAuthSystem to make it testable.
class TestableProximityAuthSystem : public ProximityAuthSystem {
 public:
  TestableProximityAuthSystem(ScreenlockType screenlock_type,
                              ProximityAuthClient* proximity_auth_client,
                              std::unique_ptr<UnlockManager> unlock_manager,
                              base::Clock* clock,
                              ProximityAuthPrefManager* pref_manager)
      : ProximityAuthSystem(screenlock_type,
                            proximity_auth_client,
                            std::move(unlock_manager),
                            clock,
                            pref_manager),
        life_cycle_(nullptr) {}
  ~TestableProximityAuthSystem() override {}

  FakeRemoteDeviceLifeCycle* life_cycle() { return life_cycle_; }

 private:
  std::unique_ptr<RemoteDeviceLifeCycle> CreateRemoteDeviceLifeCycle(
      const RemoteDevice& remote_device) override {
    std::unique_ptr<FakeRemoteDeviceLifeCycle> life_cycle(
        new FakeRemoteDeviceLifeCycle(remote_device));
    life_cycle_ = life_cycle.get();
    return std::move(life_cycle);
  }

  FakeRemoteDeviceLifeCycle* life_cycle_;

  DISALLOW_COPY_AND_ASSIGN(TestableProximityAuthSystem);
};

}  // namespace

class ProximityAuthSystemTest : public testing::Test {
 protected:
  ProximityAuthSystemTest()
      : pref_manager_(new NiceMock<MockProximityAuthPrefManager>()),
        task_runner_(new base::TestSimpleTaskRunner()),
        thread_task_runner_handle_(task_runner_) {}

  void SetUp() override {
    user1_remote_devices_.push_back(
        CreateRemoteDevice(kUser1, "user1_device1"));
    user1_remote_devices_.push_back(
        CreateRemoteDevice(kUser1, "user1_device2"));

    user2_remote_devices_.push_back(
        CreateRemoteDevice(kUser2, "user2_device1"));
    user2_remote_devices_.push_back(
        CreateRemoteDevice(kUser2, "user2_device2"));
    user2_remote_devices_.push_back(
        CreateRemoteDevice(kUser2, "user2_device3"));

    InitProximityAuthSystem(ProximityAuthSystem::SESSION_LOCK);
    proximity_auth_system_->SetRemoteDevicesForUser(
        AccountId::FromUserEmail(kUser1), user1_remote_devices_);
    proximity_auth_system_->Start();
    LockScreen();
  }

  void TearDown() override { UnlockScreen(); }

  void InitProximityAuthSystem(ProximityAuthSystem::ScreenlockType type) {
    std::unique_ptr<MockUnlockManager> unlock_manager(
        new NiceMock<MockUnlockManager>());
    unlock_manager_ = unlock_manager.get();

    clock_.SetNow(base::Time::FromJavaTime(kTimestampBeforeReauthMs));
    ON_CALL(*pref_manager_, GetLastPasswordEntryTimestampMs())
        .WillByDefault(Return(kLastPasswordEntryTimestampMs));

    proximity_auth_system_.reset(new TestableProximityAuthSystem(
        type, &proximity_auth_client_, std::move(unlock_manager), &clock_,
        pref_manager_.get()));
  }

  void LockScreen() {
    ScreenlockBridge::Get()->SetFocusedUser(AccountId());
    ScreenlockBridge::Get()->SetLockHandler(&lock_handler_);
  }

  void FocusUser(const std::string& user_id) {
    ScreenlockBridge::Get()->SetFocusedUser(AccountId::FromUserEmail(user_id));
  }

  void UnlockScreen() { ScreenlockBridge::Get()->SetLockHandler(nullptr); }

  void SimulateSuspend() {
    proximity_auth_system_->OnSuspend();
    proximity_auth_system_->OnSuspendDone();
    task_runner_->RunUntilIdle();
  }

  FakeRemoteDeviceLifeCycle* life_cycle() {
    return proximity_auth_system_->life_cycle();
  }

  FakeLockHandler lock_handler_;
  NiceMock<MockProximityAuthClient> proximity_auth_client_;
  std::unique_ptr<TestableProximityAuthSystem> proximity_auth_system_;
  MockUnlockManager* unlock_manager_;
  base::SimpleTestClock clock_;
  std::unique_ptr<MockProximityAuthPrefManager> pref_manager_;

  RemoteDeviceList user1_remote_devices_;
  RemoteDeviceList user2_remote_devices_;

  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  base::ThreadTaskRunnerHandle thread_task_runner_handle_;

 private:
  ScopedDisableLoggingForTesting disable_logging_;

  DISALLOW_COPY_AND_ASSIGN(ProximityAuthSystemTest);
};

TEST_F(ProximityAuthSystemTest, SetRemoteDevicesForUser_NotStarted) {
  InitProximityAuthSystem(ProximityAuthSystem::SESSION_LOCK);

  AccountId account1 = AccountId::FromUserEmail(kUser1);
  AccountId account2 = AccountId::FromUserEmail(kUser2);
  proximity_auth_system_->SetRemoteDevicesForUser(account1,
                                                  user1_remote_devices_);
  proximity_auth_system_->SetRemoteDevicesForUser(account2,
                                                  user2_remote_devices_);

  CompareRemoteDeviceLists(
      user1_remote_devices_,
      proximity_auth_system_->GetRemoteDevicesForUser(account1));

  CompareRemoteDeviceLists(
      user2_remote_devices_,
      proximity_auth_system_->GetRemoteDevicesForUser(account2));

  CompareRemoteDeviceLists(
      RemoteDeviceList(),
      proximity_auth_system_->GetRemoteDevicesForUser(
          AccountId::FromUserEmail("non_existent_user@google.com")));
}

TEST_F(ProximityAuthSystemTest, SetRemoteDevicesForUser_Started) {
  InitProximityAuthSystem(ProximityAuthSystem::SESSION_LOCK);
  AccountId account1 = AccountId::FromUserEmail(kUser1);
  AccountId account2 = AccountId::FromUserEmail(kUser2);
  proximity_auth_system_->SetRemoteDevicesForUser(account1,
                                                  user1_remote_devices_);
  proximity_auth_system_->Start();
  proximity_auth_system_->SetRemoteDevicesForUser(account2,
                                                  user2_remote_devices_);

  CompareRemoteDeviceLists(
      user1_remote_devices_,
      proximity_auth_system_->GetRemoteDevicesForUser(account1));

  CompareRemoteDeviceLists(
      user2_remote_devices_,
      proximity_auth_system_->GetRemoteDevicesForUser(account2));
}

TEST_F(ProximityAuthSystemTest, FocusRegisteredUser) {
  EXPECT_FALSE(life_cycle());
  EXPECT_EQ(std::string(),
            ScreenlockBridge::Get()->focused_account_id().GetUserEmail());

  RemoteDeviceLifeCycle* unlock_manager_life_cycle = nullptr;
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
      .WillOnce(SaveArg<0>(&unlock_manager_life_cycle));
  FocusUser(kUser1);

  EXPECT_EQ(life_cycle(), unlock_manager_life_cycle);
  EXPECT_TRUE(life_cycle());
  EXPECT_TRUE(life_cycle()->started());
  EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_id);

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AtLeast(1));
}

TEST_F(ProximityAuthSystemTest, FocusUnregisteredUser) {
  EXPECT_FALSE(life_cycle());
  EXPECT_EQ(std::string(),
            ScreenlockBridge::Get()->focused_account_id().GetUserEmail());
  EXPECT_FALSE(life_cycle());

  FocusUser(kUser2);
  EXPECT_FALSE(life_cycle());
}

TEST_F(ProximityAuthSystemTest, ToggleFocus_RegisteredUsers) {
  proximity_auth_system_->SetRemoteDevicesForUser(
      AccountId::FromUserEmail(kUser2), user2_remote_devices_);

  RemoteDeviceLifeCycle* life_cycle1 = nullptr;
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
      .WillOnce(SaveArg<0>(&life_cycle1));
  FocusUser(kUser1);
  EXPECT_EQ(kUser1, life_cycle1->GetRemoteDevice().user_id);

  RemoteDeviceLifeCycle* life_cycle2 = nullptr;
  {
    InSequence sequence;
    EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
        .Times(AtLeast(1));
    EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
        .WillOnce(SaveArg<0>(&life_cycle2));
  }
  FocusUser(kUser2);
  EXPECT_EQ(kUser2, life_cycle2->GetRemoteDevice().user_id);

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AtLeast(1));
}

TEST_F(ProximityAuthSystemTest, ToggleFocus_UnregisteredUsers) {
  FocusUser(kUser2);
  EXPECT_FALSE(life_cycle());

  FocusUser("unregistered-user");
  EXPECT_FALSE(life_cycle());

  FocusUser(kUser2);
  EXPECT_FALSE(life_cycle());
}

TEST_F(ProximityAuthSystemTest, ToggleFocus_RegisteredAndUnregisteredUsers) {
  // Focus User 1, who is registered. This should create a new life cycle.
  RemoteDeviceLifeCycle* life_cycle = nullptr;
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
      .WillOnce(SaveArg<0>(&life_cycle));
  FocusUser(kUser1);
  EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_id);

  // User 2 has not been registered yet, so focusing them should not create a
  // new life cycle.
  life_cycle = nullptr;
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr));
  FocusUser(kUser2);
  EXPECT_FALSE(life_cycle);

  // Focusing back to User 1 should recreate a new life cycle.
  life_cycle = nullptr;
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
      .WillOnce(SaveArg<0>(&life_cycle));
  FocusUser(kUser1);
  EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_id);

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AtLeast(1));
}

TEST_F(ProximityAuthSystemTest, ToggleFocus_SameUserRefocused) {
  RemoteDeviceLifeCycle* life_cycle = nullptr;
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(_))
      .WillOnce(SaveArg<0>(&life_cycle));
  FocusUser(kUser1);
  EXPECT_EQ(kUser1, life_cycle->GetRemoteDevice().user_id);

  // Focusing the user again should be idempotent. The screenlock UI may call
  // focus on the same user multiple times.
  // SetRemoteDeviceLifeCycle() is only expected to be called once.
  FocusUser(kUser1);

  // The RemoteDeviceLifeCycle should be nulled upon destruction.
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AtLeast(1));
}

TEST_F(ProximityAuthSystemTest, RestartSystem_UnregisteredUserFocused) {
  FocusUser(kUser2);

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AnyNumber());
  proximity_auth_system_->Stop();
  proximity_auth_system_->Start();
  EXPECT_FALSE(life_cycle());
}

TEST_F(ProximityAuthSystemTest, StopSystem_RegisteredUserFocused) {
  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
  FocusUser(kUser1);

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AtLeast(1));
  proximity_auth_system_->Stop();

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
  proximity_auth_system_->Start();
  EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_id);
}

TEST_F(ProximityAuthSystemTest, OnLifeCycleStateChanged) {
  FocusUser(kUser1);

  EXPECT_CALL(*unlock_manager_, OnLifeCycleStateChanged());
  life_cycle()->ChangeState(RemoteDeviceLifeCycle::State::FINDING_CONNECTION);

  EXPECT_CALL(*unlock_manager_, OnLifeCycleStateChanged());
  life_cycle()->ChangeState(RemoteDeviceLifeCycle::State::AUTHENTICATING);

  EXPECT_CALL(*unlock_manager_, OnLifeCycleStateChanged());
  life_cycle()->ChangeState(
      RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
}

TEST_F(ProximityAuthSystemTest, OnAuthAttempted) {
  FocusUser(kUser1);
  EXPECT_CALL(*unlock_manager_, OnAuthAttempted(_));
  proximity_auth_system_->OnAuthAttempted(AccountId::FromUserEmail(kUser1));
}

TEST_F(ProximityAuthSystemTest, Suspend_ScreenUnlocked) {
  UnlockScreen();
  EXPECT_FALSE(life_cycle());
  SimulateSuspend();
  EXPECT_FALSE(life_cycle());
}

TEST_F(ProximityAuthSystemTest, Suspend_UnregisteredUserFocused) {
  SimulateSuspend();
  EXPECT_FALSE(life_cycle());
}

TEST_F(ProximityAuthSystemTest, Suspend_RegisteredUserFocused) {
  FocusUser(kUser1);

  {
    InSequence sequence;
    EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
        .Times(AtLeast(1));
    EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(NotNull()));
    SimulateSuspend();
  }

  EXPECT_EQ(kUser1, life_cycle()->GetRemoteDevice().user_id);

  EXPECT_CALL(*unlock_manager_, SetRemoteDeviceLifeCycle(nullptr))
      .Times(AtLeast(1));
}

TEST_F(ProximityAuthSystemTest, ForcePasswordReauth) {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      proximity_auth::switches::kEnableForcePasswordReauth);
  ON_CALL(*pref_manager_, GetLastPasswordEntryTimestampMs())
      .WillByDefault(Return(kTimestampAfterReauthMs));
  EXPECT_CALL(proximity_auth_client_,
              UpdateScreenlockState(ScreenlockState::PASSWORD_REAUTH));
  FocusUser(kUser1);
  EXPECT_FALSE(life_cycle());
}

}  // namespace proximity_auth
