// Copyright 2021 The Chromium OS 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 "federated/session_manager_proxy.h"

#include <memory>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <base/check.h>
#include <base/memory/ptr_util.h>
#include <base/memory/ref_counted.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <session_manager/dbus-proxy-mocks.h>

#include "federated/utils.h"

namespace federated {
namespace {

using ::testing::_;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::Test;

class MockSessionManagerObserver : public SessionManagerObserverInterface {
 public:
  ~MockSessionManagerObserver() = default;

  MOCK_METHOD(void, OnSessionStarted, (), (override));
  MOCK_METHOD(void, OnSessionStopped, (), (override));
};

}  // namespace

class SessionManagerProxyTest : public Test {
 public:
  SessionManagerProxyTest()
      : mock_session_manager_interface_proxy_(
            new StrictMock<org::chromium::SessionManagerInterfaceProxyMock>()) {
  }

  SessionManagerProxyTest(const SessionManagerProxyTest&) = delete;
  SessionManagerProxyTest& operator=(const SessionManagerProxyTest&) = delete;

  void SetUp() override {
    EXPECT_CALL(*mock_session_manager_interface_proxy_,
                DoRegisterSessionStateChangedSignalHandler(_, _))
        .WillOnce(SaveArg<0>(&session_state_changed_callback_));

    session_manager_proxy_ = std::make_unique<SessionManagerProxy>(
        base::WrapUnique<org::chromium::SessionManagerInterfaceProxyInterface>(
            mock_session_manager_interface_proxy_));
  }

  void TearDown() override {
    session_manager_proxy_.reset();
    Mock::VerifyAndClearExpectations(mock_session_manager_interface_proxy_);
  }

  // Mocks the session state change signals
  void InvokeSessionStateChange(const std::string& session_state) {
    session_state_changed_callback_.Run(session_state);
  }

  SessionManagerProxy* session_manager_proxy() const {
    CHECK_NE(session_manager_proxy_, nullptr);
    return session_manager_proxy_.get();
  }

  // Sets the primary session and the EXPECT_CALL of RetrievePrimarySession.
  void SetPrimarySession(const std::string& username,
                         const std::string& sanitized_username) {
    primary_session_ = {username, sanitized_username};

    EXPECT_CALL(*mock_session_manager_interface_proxy_,
                RetrievePrimarySession(_, _, _, _))
        .Times(1)
        .WillOnce(
            Invoke(this, &SessionManagerProxyTest::RetrievePrimarySessionImpl));
  }

  // Sets the session state and the EXPECT_CALL of RetrieveSessionState.
  void SetSessionState(const std::string& state) {
    session_state_ = state;

    EXPECT_CALL(*mock_session_manager_interface_proxy_,
                RetrieveSessionState(_, _, _))
        .Times(1)
        .WillOnce(
            Invoke(this, &SessionManagerProxyTest::RetrieveSessionStateImpl));
  }

 private:
  // Invoked when SessionManagerInterfaceProxyMock::RetrievePrimarySession() is
  // called.
  bool RetrievePrimarySessionImpl(std::string* const username,
                                  std::string* const sanitized_username,
                                  brillo::ErrorPtr* /* error */,
                                  int /* timeout_ms */) const {
    *username = primary_session_.first;  // Set in SetPrimarySession().
    *sanitized_username = primary_session_.second;

    return true;
  }

  // Invoked when SessionManagerInterfaceProxyMock::RetrieveSessionState() is
  // called.
  bool RetrieveSessionStateImpl(std::string* const state,
                                brillo::ErrorPtr* /* error */,
                                int /* timeout_ms */) const {
    *state = session_state_;  // Set in SetSessionState().
    return true;
  }

  // Primary session consists of username and sanitized_username.
  std::pair<std::string, std::string> primary_session_;
  std::string session_state_;

  org::chromium::SessionManagerInterfaceProxyMock* const
      mock_session_manager_interface_proxy_;

  std::unique_ptr<SessionManagerProxy> session_manager_proxy_;

  base::RepeatingCallback<void(const std::string& state)>
      session_state_changed_callback_;
};

// Tests that GetSanitizedUsername can get the user_hash of current primary
// session.
TEST_F(SessionManagerProxyTest, GetSanitizedUsername) {
  SetPrimarySession("user1", "hash1");
  EXPECT_EQ(session_manager_proxy()->GetSanitizedUsername(), "hash1");

  SetPrimarySession("user2", "hash2");
  EXPECT_EQ(session_manager_proxy()->GetSanitizedUsername(), "hash2");
}

// Tests that RetrieveSessionState works. RetrieveSessionState can get whatever
// session state, although only kSessionStartedState and kSessionStoppedState
// are concerned.
TEST_F(SessionManagerProxyTest, RetrieveSessionState) {
  SetSessionState(kSessionStartedState);
  EXPECT_EQ(session_manager_proxy()->RetrieveSessionState(),
            kSessionStartedState);

  SetSessionState(kSessionStoppedState);
  EXPECT_EQ(session_manager_proxy()->RetrieveSessionState(),
            kSessionStoppedState);

  SetSessionState("unknown_state");
  EXPECT_EQ(session_manager_proxy()->RetrieveSessionState(), "unknown_state");
}

// Tests that session_manager_proxy can invoke observers when session state
// changes.
TEST_F(SessionManagerProxyTest, OnSessionStateChanged) {
  StrictMock<MockSessionManagerObserver> mock_observer;
  session_manager_proxy()->AddObserver(&mock_observer);

  // Generates a random state array, records the counts of started and stopped
  // state.
  std::vector<std::string> state_vector;
  int started_state_count = 0;
  int stopped_state_count = 0;

  const std::vector<std::string> available_states = {
      kSessionStartedState, kSessionStoppedState, "unknown_state"};
  static unsigned int seed = time(NULL) + 1234;
  for (size_t i = 0; i < 100; i++) {
    const int index = rand_r(&seed) % 3;
    if (index == 0)
      started_state_count++;
    else if (index == 1)
      stopped_state_count++;

    state_vector.push_back(available_states[index]);
  }

  // Each time OnSessionStateChanged with state = kSessionStartedState,
  // observer's OnSessionStarted is invoked.
  EXPECT_CALL(mock_observer, OnSessionStarted()).Times(started_state_count);
  // Each time OnSessionStateChanged with state = kSessionStoppedState,
  // observer's OnSessionStopped is invoked.
  EXPECT_CALL(mock_observer, OnSessionStopped()).Times(stopped_state_count);

  for (const auto& state : state_vector) {
    InvokeSessionStateChange(state);
  }
}

}  // namespace federated
