// Copyright 2019 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 "biod/power_manager_client.h"

#include <base/bind.h>
#include <base/check.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <chromeos/dbus/service_constants.h>
#include <google/protobuf/message_lite.h>

#include "power_manager/proto_bindings/input_event.pb.h"

namespace {

// Deserializes |serialized_protobuf| to |protobuf_out| and returns true on
// success.
bool DeserializeProtocolBuffer(const std::vector<uint8_t>& serialized_protobuf,
                               google::protobuf::MessageLite* protobuf_out) {
  CHECK(protobuf_out);
  if (serialized_protobuf.empty())
    return false;
  return protobuf_out->ParseFromArray(&serialized_protobuf.front(),
                                      serialized_protobuf.size());
}

}  // namespace

namespace biod {

std::unique_ptr<PowerManagerClientInterface> PowerManagerClient::Create(
    const scoped_refptr<dbus::Bus>& bus) {
  return base::WrapUnique(new PowerManagerClient(bus));
}

PowerManagerClient::PowerManagerClient(const scoped_refptr<dbus::Bus>& bus) {
  proxy_ = std::make_unique<org::chromium::PowerManagerProxy>(bus);
  // Register Input Event signal Handler.
  proxy_->RegisterInputEventSignalHandler(
      base::Bind(&PowerManagerClient::InputEvent, weak_factory_.GetWeakPtr()),
      base::Bind(&PowerManagerClient::OnSignalConnected,
                 weak_factory_.GetWeakPtr()));
}

void PowerManagerClient::AddObserver(PowerEventObserver* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

bool PowerManagerClient::HasObserver(PowerEventObserver* observer) {
  DCHECK(observer);
  return observers_.HasObserver(observer);
}

void PowerManagerClient::RemoveObserver(PowerEventObserver* observer) {
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

void PowerManagerClient::InputEvent(
    const std::vector<uint8_t>& serialized_proto) {
  power_manager::InputEvent proto;
  if (!DeserializeProtocolBuffer(serialized_proto, &proto)) {
    LOG(ERROR) << "Failed to parse InputEvent signal.";
    return;
  }
  base::TimeTicks timestamp =
      base::TimeTicks::FromInternalValue(proto.timestamp());
  if (proto.type() == power_manager::InputEvent_Type_POWER_BUTTON_DOWN ||
      proto.type() == power_manager::InputEvent_Type_POWER_BUTTON_UP) {
    const bool down =
        (proto.type() == power_manager::InputEvent_Type_POWER_BUTTON_DOWN);
    for (auto& observer : observers_)
      observer.PowerButtonEventReceived(down, timestamp);
  }
}

void PowerManagerClient::OnSignalConnected(const std::string& interface_name,
                                           const std::string& signal_name,
                                           bool success) {
  LOG(INFO) << __func__ << " interface: " << interface_name
            << " signal: " << signal_name << "success: " << success;
  if (!success) {
    LOG(ERROR) << "Failed to connect signal " << signal_name << " to interface "
               << interface_name;
  }
}

}  // namespace biod
