// Copyright 2020 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 "typecd/session_manager_proxy.h"

#include <base/bind.h>
#include <base/check.h>

namespace typecd {

namespace {

void OnSignalConnected(const std::string& interface,
                       const std::string& signal,
                       bool success) {
  if (!success) {
    LOG(ERROR) << "Could not connect to signal " << signal << " on interface "
               << interface;
  }
}

}  // namespace

SessionManagerProxy::SessionManagerProxy(scoped_refptr<dbus::Bus> bus)
    : proxy_(bus), weak_ptr_factory_(this) {
  proxy_.RegisterScreenIsLockedSignalHandler(
      base::BindRepeating(&SessionManagerProxy::OnScreenIsLocked,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&OnSignalConnected));
  proxy_.RegisterScreenIsUnlockedSignalHandler(
      base::BindRepeating(&SessionManagerProxy::OnScreenIsUnlocked,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&OnSignalConnected));
  proxy_.RegisterSessionStateChangedSignalHandler(
      base::BindRepeating(&SessionManagerProxy::OnSessionStateChanged,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&OnSignalConnected));
}

void SessionManagerProxy::AddObserver(
    SessionManagerObserverInterface* observer) {
  CHECK(observer) << "Invalid observer object";
  observer_list_.AddObserver(observer);
}

bool SessionManagerProxy::IsScreenLocked() {
  brillo::ErrorPtr error;
  bool locked;
  if (!proxy_.IsScreenLocked(&locked, &error)) {
    LOG(ERROR) << "Failed to get lockscreen state: " << error->GetMessage();
    return false;
  }

  return locked;
}

bool SessionManagerProxy::IsSessionStarted() {
  brillo::ErrorPtr error;
  std::string state;
  if (!proxy_.RetrieveSessionState(&state, &error)) {
    LOG(ERROR) << "Failed to get session state: " << error->GetMessage();
    return false;
  }

  return state == "started";
}

void SessionManagerProxy::OnScreenIsLocked() {
  for (SessionManagerObserverInterface& observer : observer_list_)
    observer.OnScreenIsLocked();
}

void SessionManagerProxy::OnScreenIsUnlocked() {
  for (SessionManagerObserverInterface& observer : observer_list_)
    observer.OnScreenIsUnlocked();
}

void SessionManagerProxy::OnSessionStateChanged(const std::string& state) {
  if (state == "started") {
    // Guest sessions are treated the same as login screens.
    bool guest_active;
    brillo::ErrorPtr error;
    if (!proxy_.IsGuestSessionActive(&guest_active, &error)) {
      LOG(ERROR) << "Failed to check guest session state: "
                 << error->GetMessage();
      return;
    }

    if (guest_active) {
      LOG(INFO) << "Guest session started.";
      return;
    }

    // If it's not a guest session, proceed with notifying the observers (they
    // can then change alt modes if appropriate).
    for (SessionManagerObserverInterface& observer : observer_list_)
      observer.OnSessionStarted();
  } else if (state == "stopped") {
    for (SessionManagerObserverInterface& observer : observer_list_)
      observer.OnSessionStopped();
  }
}

}  // namespace typecd
