// Copyright 2018 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 "cecservice/cec_device.h"

#include <fcntl.h>
#include <linux/cec-funcs.h>
#include <poll.h>
#include <string.h>

#include <deque>
#include <list>
#include <map>
#include <unordered_map>
#include <utility>

#include <base/bind.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>

namespace cecservice {

class StateBase;

class CecDeviceImpl::Impl {
 public:
  // Enum identifiying CEC device states.
  enum class State {
    kStart,  // State when no physical address is known, in this state we
             // are only allowed to send image view on message.
    kNoLogicalAddress,  // The physical address is known but the logical
                        // address is not (yet) configured.
    kProbingTvAddress,  // Obtaining logical address of the TV.
    kReady,     // All is set up, we are free to send any type of messages.
    kDisabled,  // Device is disabled due to previous errors.
  };

  Impl(std::unique_ptr<CecFd> fd, const base::FilePath& device_path);

  // Performs object initialization. Returns false if the initialization
  // failed and object is unusable.
  bool Init();

  // Implementation of respective methods from CecDevice:
  void GetTvPowerStatus(CecDevice::GetTvPowerStatusCallback callback);
  void SetStandBy();
  void SetWakeUp();

  // Enters a given state.
  void EnterState(State state);

  // Adds active source message to the queue.
  void EnqueueActiveSourceMessage();

  // Adds Image View On message to the queue.
  void EnqueueImageViewOnMessage();

  // Adds Stand By message to the queue.
  void EnqueueStandByMessage();

  // Enqueues Get Power Status request.
  void EnqueueGetTvPowerStatusMessage(
      CecDevice::GetTvPowerStatusCallback callback);

  // Enqueues a message, returns true if the message was added to the queue.
  bool EnqueueMessage(struct cec_msg msg);

  // Flags that the we didn't manage to find a TV. Will make the object send
  // request to address 0.
  void SetTvProbingCompleted();

  // Attempts to send next queued message, true if successful, false if an
  // unrecoverable error occurred.
  bool SendNextPendingMessage();

  // Sends provided message.
  CecFd::TransmitResult SendMessage(struct cec_msg* msg);

  // Get path to device node (for logging purposes).
  const std::string& GetDevicePathString() const;

  // Processes report physical address message. If that message
  // comes from a TV, updates a TV address.
  void ProcessReportPhysicalAddress(const struct cec_msg& msg);

  // Returns true is we know TV address.
  bool HasTvAddress() const;

  // Sets the current TV address to invalid.
  void ResetTvAddress();

  // Returns true if there are any queued messages.
  bool MessagesInOutputQueue() const;

  // Returns true if next scheduled message is directed to a TV.
  bool NeedsToQueryTvAddress() const;

  // Returns true if this is a message directed to the TV
  // and should be send to whatever is the current TV's
  // logical address.
  bool IsMessageDirectedToTv(const struct cec_msg& msg) const;

 private:
  // Represents 'get TV power request' that either is to be sent or has been
  // sent and awaits response.
  struct RequestInFlight {
    // The callback to invoke when the request completes.
    CecDevice::GetTvPowerStatusCallback callback;

    // Message id assigned by CEC API or 0 if the request has not been sent yet.
    uint32_t sequence_id;
  };

  // Schedules watching for write readiness on the fd (if demanded by the
  // current state).
  void RequestWriteWatch();

  // Processes messages lost event from CEC. Always returns true.
  bool ProcessMessagesLostEvent(const struct cec_event_lost_msgs& event);

  // Acts on process update event from CEC core. If this method returns false
  // then an unexpected error was encountered and the object should be disabled.
  bool ProcessStateChangeEvent(const struct cec_event_state_change& event);

  // Processes incoming events. If false is returned, then unexpected failure
  // occurred and the object should be disabled.
  bool ProcessEvents();

  // Attempts to read incoming data from the fd. If false is returned, then
  // an unexpected failure occurred and the object should be disabled.
  bool ProcessRead();

  // Called when the fd is ready to be written to. Delegates the write
  // operation to the current state. False is returned in case of unrecoverable
  // error occurred.
  bool ProcessWrite();

  // Processes response received to get power status request. Returns false if
  // the message is not a response to a previously sent request.
  bool ProcessPowerStatusResponse(const struct cec_msg& msg);

  // Handles responses to previously sent requests.
  void ProcessSentMessage(const struct cec_msg& msg);

  // Handles messages directed to us.
  void ProcessIncomingMessage(struct cec_msg* msg);

  // Sets the type of logical address on the adapter (if it has not been yet
  // configured), returns false if the operation failed. Here we are only
  // choosing the type of the address, the kernel will then do the probing and
  // try to allocate first free address of the chosen type. The address type
  // selection is permanent and survives device reconnects (every time EDID
  // shows up, kernel will redo the probing and potentially can end up selecting
  // different logical address). Since this selection is permanent it is
  // sufficient to do it only once when we create the device.
  bool SetLogicalAddress();

  // Handles fd event.
  void OnFdEvent(CecFd::EventType event);

  // Immediately responds to all currently ongoing queries.
  void RespondToAllQueries(TvPowerStatus response);

  // Disables device.
  void DisableDevice();

  // Instances of all states.
  std::unordered_map<State, std::unique_ptr<StateBase>> states_;

  // Current state.
  StateBase* state_;

  // The descriptor associated with the device.
  std::unique_ptr<CecFd> fd_;

  // Path to the device, for logging purposes only.
  const base::FilePath device_path_;

  // Current physical address.
  uint16_t physical_address_ = CEC_PHYS_ADDR_INVALID;

  // Current logical address.
  uint8_t logical_address_ = CEC_LOG_ADDR_INVALID;

  // TV logical address.
  uint8_t tv_logical_address_ = CEC_LOG_ADDR_INVALID;

  // Queue of messages we are about to send.
  std::deque<struct cec_msg> message_queue_;

  // Queue of requests that are in flight.
  std::list<RequestInFlight> requests_;

  // Flag indicating if we believe we are the active source.
  bool active_source_ = false;

  // Flag saying if we should probe the TV address if it is unknown.
  bool probe_tv_address_if_unknown_ = true;

  base::WeakPtrFactory<Impl> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(Impl);
};

// Maximum size of a cec device's queue with outgoing messages, roughly
// 10 secs of continus flow of messages.
//
// Extern to make it avaiable to UTs.
extern const size_t kCecDeviceMaxTxQueueSize = 250;

namespace {
struct cec_msg CreateMessage(uint16_t destination_address) {
  struct cec_msg message;
  cec_msg_init(&message, CEC_LOG_ADDR_UNREGISTERED, destination_address);
  return message;
}

void SetMessageSourceAddress(uint16_t source_address, struct cec_msg* msg) {
  if (source_address == CEC_LOG_ADDR_INVALID) {
    source_address = CEC_LOG_ADDR_UNREGISTERED;
  }
  msg->msg[0] = (source_address << 4) | cec_msg_destination(msg);
}

void SetMessageDestinationAddress(uint16_t dest_address, struct cec_msg* msg) {
  msg->msg[0] = (cec_msg_initiator(msg) << 4) | dest_address;
}

TvPowerStatus GetPowerStatus(const struct cec_msg& msg) {
  uint8_t power_status;
  cec_ops_report_power_status(&msg, &power_status);
  switch (power_status) {
    case CEC_OP_POWER_STATUS_ON:
      return kTvPowerStatusOn;
    case CEC_OP_POWER_STATUS_STANDBY:
      return kTvPowerStatusStandBy;
    case CEC_OP_POWER_STATUS_TO_ON:
      return kTvPowerStatusToOn;
    case CEC_OP_POWER_STATUS_TO_STANDBY:
      return kTvPowerStatusToStandBy;
    default:
      return kTvPowerStatusUnknown;
  }
}

}  // namespace

// Bases class for all states the CecDevice object can be in.
class StateBase {
 public:
  // Assigned the device imp object to object.
  void Init(CecDeviceImpl::Impl* device);
  // Called when the state is being entered.
  virtual void Enter();
  // Called when 'get TV power status' request is made by a user.
  virtual void GetTvPowerStatus(
      CecDevice::GetTvPowerStatusCallback callback) = 0;
  // Called to learn if the state wants to write sth out on the fd.
  virtual bool NeedsWrite() = 0;
  // Called when Stand By request is made by a user.
  virtual void SetStandBy() = 0;
  // Called when Stand By request is made by a user.
  virtual void SetWakeUp() = 0;
  // Called when a message is sent (or response received),
  // should return true if the message was handled by the state and false
  // otherwise.
  virtual bool ProcessResponse(const cec_msg& msg);
  // Called whenever fd is available for writing.
  virtual bool ProcessWrite();
  // Called whenever an event saying that the kernel is dropping messages is
  // recevied.
  virtual void ProcessMessagesLostEvent();

  StateBase();

  virtual ~StateBase();

 protected:
  CecDeviceImpl::Impl* device_;

 private:
  DISALLOW_COPY_AND_ASSIGN(StateBase);
};

// The state the object transitions to whenever an unrecoverable
// error is encountered. We do nothing in this state.
class DisabledState : public StateBase {
 public:
  // StateBase overrides:
  void GetTvPowerStatus(CecDevice::GetTvPowerStatusCallback callback) override;
  bool NeedsWrite() override;
  void SetStandBy() override;
  void SetWakeUp() override;
  bool ProcessWrite() override;
};

// The state when we don't have a physical address. The only action performed
// by this state is an attempt to send 'image view on' request when requested
// to set wake up.
class StartState : public StateBase {
 public:
  // StateBase overrides:
  void GetTvPowerStatus(CecDevice::GetTvPowerStatusCallback callback) override;
  bool NeedsWrite() override;
  void SetStandBy() override;
  void SetWakeUp() override;
};

// The state where we don't have a logical address yet. All requests received
// in this state are queued up.
class NoLogicalAddressState : public StateBase {
 public:
  // StateBase overrides:
  void GetTvPowerStatus(CecDevice::GetTvPowerStatusCallback callback) override;
  bool NeedsWrite() override;
  void SetStandBy() override;
  void SetWakeUp() override;
};

// The state where we probe TV's address. All requests are being queued up.
class ProbingTvAddressState : public StateBase {
 public:
  // StateBase overrides:
  void Enter() override;
  void GetTvPowerStatus(CecDevice::GetTvPowerStatusCallback callback) override;
  bool NeedsWrite() override;
  void SetStandBy() override;
  void SetWakeUp() override;
  bool ProcessResponse(const cec_msg& msg) override;
  bool ProcessWrite() override;
  void ProcessMessagesLostEvent() override;

 private:
  // Represent state TV address querying op.
  enum class SubState {
    kStart,              // Inital state.
    kProbing0,           // The probe for address 0 was sent.
    kProbing0Completed,  // The probe for address 0 is completed.
    kProbing14,          // The probe for address 14 was sent.
  } subState_ = SubState::kStart;
};

class ReadyState : public StateBase {
 public:
  // StateBase overrides:
  void GetTvPowerStatus(CecDevice::GetTvPowerStatusCallback callback) override;
  bool NeedsWrite() override;
  void SetStandBy() override;
  void SetWakeUp() override;
  bool ProcessResponse(const cec_msg& msg) override;
  bool ProcessWrite() override;
};

void CecDeviceImpl::Impl::EnqueueActiveSourceMessage() {
  struct cec_msg msg = CreateMessage(CEC_LOG_ADDR_BROADCAST);
  cec_msg_active_source(&msg, physical_address_);
  EnqueueMessage(msg);
}

void CecDeviceImpl::Impl::EnqueueImageViewOnMessage() {
  struct cec_msg msg = CreateMessage(CEC_LOG_ADDR_TV);
  cec_msg_image_view_on(&msg);
  EnqueueMessage(msg);
}

void CecDeviceImpl::Impl::EnqueueStandByMessage() {
  struct cec_msg msg = CreateMessage(CEC_LOG_ADDR_TV);
  cec_msg_standby(&msg);
  EnqueueMessage(msg);
}

void CecDeviceImpl::Impl::EnqueueGetTvPowerStatusMessage(
    CecDevice::GetTvPowerStatusCallback callback) {
  struct cec_msg msg = CreateMessage(CEC_LOG_ADDR_TV);
  cec_msg_give_device_power_status(&msg, 1);
  if (EnqueueMessage(msg)) {
    requests_.push_back({std::move(callback), 0});
  } else {
    std::move(callback).Run(kTvPowerStatusError);
  }
}

bool CecDeviceImpl::Impl::EnqueueMessage(struct cec_msg msg) {
  if (message_queue_.size() < kCecDeviceMaxTxQueueSize) {
    message_queue_.push_back(msg);
    return true;
  } else {
    LOG(ERROR) << base::StringPrintf(
        "Output queue size too large, message 0x%x not enqueued",
        cec_msg_opcode(&msg));
    return false;
  }
}

void CecDeviceImpl::Impl::SetTvProbingCompleted() {
  probe_tv_address_if_unknown_ = false;
}

CecDeviceImpl::CecDeviceImpl(std::unique_ptr<CecFd> fd,
                             const base::FilePath& device_path)
    : impl_(std::make_unique<Impl>(std::move(fd), device_path)) {}

CecDeviceImpl::~CecDeviceImpl() = default;

bool CecDeviceImpl::Init() {
  return impl_->Init();
}

void CecDeviceImpl::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  impl_->GetTvPowerStatus(std::move(callback));
}

void CecDeviceImpl::SetStandBy() {
  impl_->SetStandBy();
}

void CecDeviceImpl::SetWakeUp() {
  impl_->SetWakeUp();
}

CecDeviceImpl::Impl::Impl(std::unique_ptr<CecFd> fd,
                          const base::FilePath& device_path)
    : fd_(std::move(fd)), device_path_(device_path) {
  states_[State::kStart] = std::make_unique<StartState>();
  states_[State::kNoLogicalAddress] = std::make_unique<NoLogicalAddressState>();
  states_[State::kProbingTvAddress] = std::make_unique<ProbingTvAddressState>();
  states_[State::kReady] = std::make_unique<ReadyState>();
  states_[State::kDisabled] = std::make_unique<DisabledState>();

  for (auto& kv : states_) {
    kv.second->Init(this);
  }

  EnterState(State::kStart);
}

bool CecDeviceImpl::Impl::Init() {
  if (!fd_->SetEventCallback(base::Bind(&CecDeviceImpl::Impl::OnFdEvent,
                                        weak_factory_.GetWeakPtr()))) {
    DisableDevice();
    return false;
  }

  if (!SetLogicalAddress()) {
    DisableDevice();
    return false;
  }

  return true;
}

void CecDeviceImpl::Impl::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  state_->GetTvPowerStatus(std::move(callback));
  RequestWriteWatch();
}

void CecDeviceImpl::Impl::SetStandBy() {
  probe_tv_address_if_unknown_ = true;

  active_source_ = false;
  state_->SetStandBy();
  RequestWriteWatch();
}

void CecDeviceImpl::Impl::SetWakeUp() {
  probe_tv_address_if_unknown_ = true;

  active_source_ = true;
  state_->SetWakeUp();
  RequestWriteWatch();
}

void CecDeviceImpl::Impl::RequestWriteWatch() {
  if (!state_->NeedsWrite())
    return;

  if (!fd_->WriteWatch()) {
    LOG(ERROR) << device_path_.value()
               << ": failed to request write watch on fd, disabling device";
    DisableDevice();
  }
}

bool CecDeviceImpl::Impl::ProcessMessagesLostEvent(
    const struct cec_event_lost_msgs& event) {
  LOG(WARNING) << device_path_.value() << ": received event lost message, lost "
               << event.lost_msgs << " messages";

  state_->ProcessMessagesLostEvent();

  // Respond to all ongoing power status queries with an error.
  std::list<RequestInFlight> ongoing;
  std::list<RequestInFlight>::iterator i = requests_.begin();
  while (i != requests_.end()) {
    if (i->sequence_id != 0) {
      ongoing.push_back(std::move(*i));
      i = requests_.erase(i);
    } else {
      i++;
    }
  }
  for (auto& request : ongoing) {
    std::move(request.callback).Run(kTvPowerStatusError);
  }

  return true;
}

bool CecDeviceImpl::Impl::ProcessStateChangeEvent(
    const struct cec_event_state_change& event) {
  physical_address_ = event.phys_addr;

  logical_address_ = CEC_LOG_ADDR_INVALID;
  if (event.log_addr_mask) {
    logical_address_ = ffs(event.log_addr_mask) - 1;
  }

  LOG(INFO) << base::StringPrintf(
      "%s: state update, physical address: 0x%x logical address: 0x%x",
      device_path_.value().c_str(), static_cast<uint32_t>(physical_address_),
      static_cast<uint32_t>(logical_address_));

  if (physical_address_ == CEC_PHYS_ADDR_INVALID) {
    message_queue_.clear();
    tv_logical_address_ = CEC_LOG_ADDR_INVALID;
    RespondToAllQueries(kTvPowerStatusAdapterNotConfigured);

    EnterState(State::kStart);
  } else if (logical_address_ == CEC_LOG_ADDR_INVALID) {
    EnterState(State::kNoLogicalAddress);
  } else {
    EnterState(State::kReady);
  }

  return true;
}

bool CecDeviceImpl::Impl::ProcessEvents() {
  struct cec_event event;

  if (!fd_->ReceiveEvent(&event)) {
    return false;
  }

  switch (event.event) {
    case CEC_EVENT_LOST_MSGS:
      return ProcessMessagesLostEvent(event.lost_msgs);
      break;
    case CEC_EVENT_STATE_CHANGE:
      return ProcessStateChangeEvent(event.state_change);
    default:
      LOG(WARNING) << base::StringPrintf("%s: unexpected cec event type: 0x%x",
                                         device_path_.value().c_str(),
                                         event.event);
      return true;
  }
}

bool CecDeviceImpl::Impl::ProcessRead() {
  struct cec_msg msg;
  if (!fd_->ReceiveMessage(&msg)) {
    return false;
  }

  if (msg.sequence) {
    ProcessSentMessage(msg);
  } else {
    ProcessIncomingMessage(&msg);
  }
  return true;
}

bool CecDeviceImpl::Impl::MessagesInOutputQueue() const {
  return !message_queue_.empty();
}

bool CecDeviceImpl::Impl::SendNextPendingMessage() {
  CHECK(!message_queue_.empty());

  struct cec_msg message = message_queue_.front();
  if (IsMessageDirectedToTv(message)) {
    uint16_t address = tv_logical_address_;
    if (address == CEC_LOG_ADDR_INVALID) {
      VLOG(1) << device_path_.value()
              << ": Unknown TV logical address, falling back on 0.";
      address = CEC_LOG_ADDR_TV;
    }

    SetMessageDestinationAddress(address, &message);
  }

  CecFd::TransmitResult ret = SendMessage(&message);
  if (ret == CecFd::TransmitResult::kBusy) {
    return true;
  }

  if (cec_msg_opcode(&message) == CEC_MSG_GIVE_DEVICE_POWER_STATUS) {
    auto iterator = std::find_if(requests_.begin(), requests_.end(),
                                 [](const RequestInFlight& request) {
                                   return request.sequence_id == 0;
                                 });
    CHECK(iterator != requests_.end());

    if (ret == CecFd::TransmitResult::kOk) {
      iterator->sequence_id = message.sequence;
    } else {
      std::move(iterator->callback).Run(kTvPowerStatusError);
      requests_.erase(iterator);
    }
  }

  message_queue_.pop_front();

  return ret != CecFd::TransmitResult::kError;
}

bool CecDeviceImpl::Impl::ProcessPowerStatusResponse(
    const struct cec_msg& msg) {
  auto iterator = std::find_if(requests_.begin(), requests_.end(),
                               [&](const RequestInFlight& request) {
                                 return request.sequence_id == msg.sequence;
                               });
  if (iterator == requests_.end()) {
    return false;
  }

  TvPowerStatus status;
  if (cec_msg_status_is_ok(&msg)) {
    status = GetPowerStatus(msg);
  } else {
    VLOG(1) << base::StringPrintf(
        "%s: power status query failed, rx_status: 0x%x tx_status: 0x%x",
        device_path_.value().c_str(), static_cast<uint32_t>(msg.rx_status),
        static_cast<uint32_t>(msg.tx_status));
    if (msg.tx_status & CEC_TX_STATUS_NACK) {
      status = kTvPowerStatusNoTv;
    } else {
      status = kTvPowerStatusError;
    }
  }

  std::move(iterator->callback).Run(status);
  requests_.erase(iterator);

  return true;
}

void CecDeviceImpl::Impl::ProcessReportPhysicalAddress(
    const struct cec_msg& msg) {
  uint16_t phys_addr;
  uint8_t prim_devtype;
  cec_ops_report_physical_addr(&msg, &phys_addr, &prim_devtype);
  if (phys_addr != 0 || prim_devtype != CEC_OP_PRIM_DEVTYPE_TV) {
    return;
  }

  tv_logical_address_ = cec_msg_initiator(&msg);
  VLOG(1) << device_path_.value()
          << ": TV's logical address: " << uint32_t(tv_logical_address_);
}

bool CecDeviceImpl::Impl::HasTvAddress() const {
  return tv_logical_address_ != CEC_LOG_ADDR_INVALID;
}

void CecDeviceImpl::Impl::ResetTvAddress() {
  tv_logical_address_ = CEC_LOG_ADDR_INVALID;
}

void CecDeviceImpl::Impl::ProcessSentMessage(const struct cec_msg& msg) {
  if (state_->ProcessResponse(msg)) {
    return;
  }

  if (ProcessPowerStatusResponse(msg)) {
    return;
  }

  if (cec_msg_status_is_ok(&msg)) {
    VLOG(1) << base::StringPrintf("%s: successfully sent message, opcode: 0x%x",
                                  device_path_.value().c_str(),
                                  cec_msg_opcode(&msg));
  } else {
    VLOG(1) << base::StringPrintf(
        "%s: failed to send message, opcode: 0x%x tx_status: 0x%x",
        device_path_.value().c_str(), cec_msg_opcode(&msg),
        static_cast<uint32_t>(msg.tx_status));
  }
}

void CecDeviceImpl::Impl::ProcessIncomingMessage(struct cec_msg* msg) {
  struct cec_msg reply;

  VLOG(1) << base::StringPrintf(
      "%s: received message, opcode:0x%x from:0x%x to:0x%x",
      device_path_.value().c_str(), cec_msg_opcode(msg),
      static_cast<unsigned>(cec_msg_initiator(msg)),
      static_cast<unsigned>(cec_msg_destination(msg)));

  switch (cec_msg_opcode(msg)) {
    case CEC_MSG_REQUEST_ACTIVE_SOURCE:
      if (active_source_) {
        cec_msg_init(&reply, logical_address_, CEC_LOG_ADDR_BROADCAST);
        cec_msg_active_source(&reply, physical_address_);
        EnqueueMessage(std::move(reply));
      }
      break;
    case CEC_MSG_ACTIVE_SOURCE:
      if (active_source_) {
        VLOG(1) << device_path_.value() << ": we ceased to be active source";
        active_source_ = false;
      }
      break;
    case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
      cec_msg_init(&reply, logical_address_, cec_msg_initiator(msg));
      cec_msg_report_power_status(&reply, CEC_OP_POWER_STATUS_ON);
      EnqueueMessage(reply);
      break;
    case CEC_MSG_REPORT_PHYSICAL_ADDR:
      ProcessReportPhysicalAddress(*msg);
      break;
    case CEC_MSG_STANDBY:
      // Ignore standby.
      break;
    case CEC_MSG_FEATURE_ABORT:
      // Ignore.
      break;
    default:
      if (!cec_msg_is_broadcast(msg)) {
        cec_msg_reply_feature_abort(msg, CEC_OP_ABORT_UNRECOGNIZED_OP);
        EnqueueMessage(std::move(*msg));
      }
      break;
  }
}

CecFd::TransmitResult CecDeviceImpl::Impl::SendMessage(struct cec_msg* msg) {
  SetMessageSourceAddress(logical_address_, msg);

  VLOG(1) << base::StringPrintf(
      "%s: transmitting message, opcode:0x%x to:0x%x",
      device_path_.value().c_str(), cec_msg_opcode(msg),
      static_cast<unsigned>(cec_msg_destination(msg)));

  return fd_->TransmitMessage(msg);
}

const std::string& CecDeviceImpl::Impl::GetDevicePathString() const {
  return device_path_.value();
}

bool CecDeviceImpl::Impl::SetLogicalAddress() {
  struct cec_log_addrs addresses = {};

  if (!fd_->GetLogicalAddresses(&addresses)) {
    return false;
  }

  // The address has already been set, so we will reuse it.
  if (addresses.num_log_addrs) {
    return true;
  }

  memset(&addresses, 0, sizeof(addresses));
  addresses.cec_version = CEC_OP_CEC_VERSION_1_4;
  addresses.vendor_id = CEC_VENDOR_ID_NONE;
  base::strlcpy(addresses.osd_name, "Chrome OS", sizeof(addresses.osd_name));
  addresses.num_log_addrs = 1;
  addresses.log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
  addresses.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_PLAYBACK;
  addresses.all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK;
  addresses.flags = CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK;

  return fd_->SetLogicalAddresses(&addresses);
}

void CecDeviceImpl::Impl::OnFdEvent(CecFd::EventType event) {
  bool ret;
  switch (event) {
    case CecFd::EventType::kPriorityRead:
      ret = ProcessEvents();
      break;
    case CecFd::EventType::kRead:
      ret = ProcessRead();
      break;
    case CecFd::EventType::kWrite:
      ret = state_->ProcessWrite();
      break;
  }

  if (!ret) {
    DisableDevice();
    return;
  }

  RequestWriteWatch();
}

bool CecDeviceImpl::Impl::IsMessageDirectedToTv(
    const struct cec_msg& msg) const {
  switch (cec_msg_opcode(&msg)) {
    case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
    case CEC_MSG_STANDBY:
    case CEC_MSG_IMAGE_VIEW_ON:
      return true;
    default:
      return false;
  }
}

bool CecDeviceImpl::Impl::NeedsToQueryTvAddress() const {
  if (HasTvAddress()) {
    return false;
  }

  if (!probe_tv_address_if_unknown_) {
    return false;
  }

  CHECK(!message_queue_.empty());
  return IsMessageDirectedToTv(message_queue_.front());
}

void CecDeviceImpl::Impl::RespondToAllQueries(TvPowerStatus response) {
  std::list<RequestInFlight> requests;
  requests.swap(requests_);

  for (auto& request : requests) {
    std::move(request.callback).Run(response);
  }
}

void CecDeviceImpl::Impl::EnterState(State state) {
  StateBase* new_state = states_[state].get();
  if (new_state == state_) {
    return;
  }

  state_ = new_state;
  state_->Enter();
}

void CecDeviceImpl::Impl::DisableDevice() {
  fd_.reset();
  message_queue_.clear();
  RespondToAllQueries(kTvPowerStatusError);
  EnterState(State::kDisabled);
}

void StateBase::Enter() {}

void StateBase::Init(CecDeviceImpl::Impl* device) {
  device_ = device;
}

bool StateBase::ProcessResponse(const cec_msg& msg) {
  return false;
}

bool StateBase::ProcessWrite() {
  return true;
}

void StateBase::ProcessMessagesLostEvent() {}

StateBase::StateBase() = default;

StateBase::~StateBase() = default;

void DisabledState::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  LOG(WARNING) << device_->GetDevicePathString()
               << ": device is disabled due to errors, unable to query";
  std::move(callback).Run(kTvPowerStatusError);
}

bool DisabledState::NeedsWrite() {
  return false;
}

void DisabledState::SetStandBy() {
  LOG(WARNING) << device_->GetDevicePathString()
               << ": device is disabled due to previous errors, ignoring "
                  "standby request";
}

void DisabledState::SetWakeUp() {
  LOG(WARNING) << device_->GetDevicePathString()
               << ": device in disabled due to previous errors, ignoring wake "
                  "up request";
}

bool DisabledState::ProcessWrite() {
  return false;
}

void StartState::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  VLOG(1) << device_->GetDevicePathString()
          << ": not configured, not querying TV power state";
  std::move(callback).Run(kTvPowerStatusAdapterNotConfigured);
}

bool StartState::NeedsWrite() {
  return false;
}

void StartState::SetStandBy() {
  VLOG(1) << device_->GetDevicePathString()
          << ": ignoring standby request, we are not connected";
}

void StartState::SetWakeUp() {
  struct cec_msg msg = CreateMessage(CEC_LOG_ADDR_TV);
  cec_msg_image_view_on(&msg);
  if (device_->SendMessage(&msg) != CecFd::TransmitResult::kOk) {
    VLOG(1) << device_->GetDevicePathString()
            << ": failed to send image view on message while in start "
               "state, we are not able to wake up this TV";
  } else {
    device_->EnqueueActiveSourceMessage();
  }
}

void NoLogicalAddressState::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  device_->EnqueueGetTvPowerStatusMessage(std::move(callback));
}

bool NoLogicalAddressState::NeedsWrite() {
  return false;
}

void NoLogicalAddressState::SetStandBy() {
  device_->EnqueueStandByMessage();
}

void NoLogicalAddressState::SetWakeUp() {
  device_->EnqueueImageViewOnMessage();
}

void ProbingTvAddressState::Enter() {
  subState_ = SubState::kStart;
}

bool ProbingTvAddressState::ProcessResponse(const cec_msg& msg) {
  bool handled = false;

  switch (cec_msg_opcode(&msg)) {
    case CEC_MSG_REPORT_PHYSICAL_ADDR:
      device_->ProcessReportPhysicalAddress(msg);
      // fallthrough
    case CEC_MSG_GIVE_PHYSICAL_ADDR:
      switch (subState_) {
        case SubState::kStart:
        case SubState::kProbing0Completed:
          break;
        case SubState::kProbing0:
          subState_ = SubState::kProbing0Completed;
          break;
        case SubState::kProbing14:
          if (!device_->HasTvAddress()) {
            VLOG(1) << device_->GetDevicePathString()
                    << ": failed to find a TV";
            device_->SetTvProbingCompleted();
            device_->EnterState(CecDeviceImpl::Impl::State::kReady);
          }
      }
      handled = true;
      break;

    default:
      break;
  }

  if (device_->HasTvAddress()) {
    device_->EnterState(CecDeviceImpl::Impl::State::kReady);
  }

  return handled;
}

bool ProbingTvAddressState::ProcessWrite() {
  struct cec_msg message;
  switch (subState_) {
    case SubState::kStart:
      cec_msg_init(&message, 0, CEC_LOG_ADDR_TV);
      cec_msg_give_physical_addr(&message, 0);
      break;
    case SubState::kProbing0Completed:
      cec_msg_init(&message, 0, CEC_LOG_ADDR_SPECIFIC);
      cec_msg_give_physical_addr(&message, 0);
      break;
    default:
      return true;
  }

  CecFd::TransmitResult ret = device_->SendMessage(&message);
  switch (ret) {
    case CecFd::TransmitResult::kBusy:
      return true;
    case CecFd::TransmitResult::kError:
      return false;
    case CecFd::TransmitResult::kOk:
      subState_ = (subState_ == SubState::kStart) ? SubState::kProbing0
                                                  : SubState::kProbing14;
      return true;
    default:
      if (subState_ == SubState::kStart) {
        subState_ = SubState::kProbing0Completed;
      } else {
        VLOG(1) << device_->GetDevicePathString() << ": failed to find a TV";
        device_->SetTvProbingCompleted();
        device_->EnterState(CecDeviceImpl::Impl::State::kReady);
      }
      return true;
  }
}

bool ProbingTvAddressState::NeedsWrite() {
  switch (subState_) {
    case SubState::kStart:
    case SubState::kProbing0Completed:
      return true;
    default:
      return false;
  }
}

void ProbingTvAddressState::ProcessMessagesLostEvent() {
  LOG(WARNING) << device_->GetDevicePathString()
               << ": losing messages, giving up on probing TV address";
  device_->SetTvProbingCompleted();
  device_->EnterState(CecDeviceImpl::Impl::State::kReady);
}

void ProbingTvAddressState::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  device_->EnqueueGetTvPowerStatusMessage(std::move(callback));
}

void ProbingTvAddressState::SetStandBy() {
  device_->EnqueueStandByMessage();
}

void ProbingTvAddressState::SetWakeUp() {
  device_->EnqueueImageViewOnMessage();
}

void ReadyState::GetTvPowerStatus(
    CecDevice::GetTvPowerStatusCallback callback) {
  device_->EnqueueGetTvPowerStatusMessage(std::move(callback));
}

bool ReadyState::NeedsWrite() {
  return device_->MessagesInOutputQueue();
}

void ReadyState::SetStandBy() {
  device_->EnqueueStandByMessage();
}

void ReadyState::SetWakeUp() {
  device_->EnqueueImageViewOnMessage();
  device_->EnqueueActiveSourceMessage();
}

bool ReadyState::ProcessResponse(const cec_msg& msg) {
  if ((msg.tx_status & CEC_TX_STATUS_NACK) &&
      device_->IsMessageDirectedToTv(msg) && device_->HasTvAddress()) {
    device_->ResetTvAddress();
    VLOG(1) << device_->GetDevicePathString()
            << ": message directed to TV not acked. "
            << "Setting TV address to unknown";
  }

  return false;
}

bool ReadyState::ProcessWrite() {
  if (!device_->MessagesInOutputQueue()) {
    return true;
  }

  if (device_->NeedsToQueryTvAddress()) {
    device_->EnterState(CecDeviceImpl::Impl::State::kProbingTvAddress);
    return true;
  }

  return device_->SendNextPendingMessage();
}

CecDeviceFactoryImpl::CecDeviceFactoryImpl(const CecFdOpener* cec_fd_opener)
    : cec_fd_opener_(cec_fd_opener) {}

CecDeviceFactoryImpl::~CecDeviceFactoryImpl() = default;

std::unique_ptr<CecDevice> CecDeviceFactoryImpl::Create(
    const base::FilePath& path) const {
  std::unique_ptr<CecFd> fd = cec_fd_opener_->Open(path, O_NONBLOCK);
  if (!fd) {
    return nullptr;
  }

  struct cec_caps caps;
  if (!fd->GetCapabilities(&caps)) {
    return nullptr;
  }

  LOG(INFO) << base::StringPrintf(
      "CEC adapter: %s, driver:%s name:%s caps:0x%x", path.value().c_str(),
      caps.driver, caps.name, caps.capabilities);

  // At the moment the only adapters supported are the ones that:
  // - handle configuration of physical address on their own (i.e. don't have
  // CEC_CAP_PHYS_ADDR flag set)
  // - allow us to configure logical addrresses (i.e. have CEC_CAP_LOG_ADDRS
  // set)
  if ((caps.capabilities & CEC_CAP_PHYS_ADDR) ||
      !(caps.capabilities & CEC_CAP_LOG_ADDRS)) {
    LOG(WARNING) << path.value()
                 << ": device does not have required capabilities to function "
                    "with this service";
    return nullptr;
  }

  uint32_t mode = CEC_MODE_EXCL_INITIATOR | CEC_MODE_EXCL_FOLLOWER;
  if (!fd->SetMode(mode)) {
    LOG(ERROR) << path.value()
               << ": failed to set an exclusive initiator mode on the device";
    return nullptr;
  }

  auto device = std::make_unique<CecDeviceImpl>(std::move(fd), path);
  if (!device->Init()) {
    return nullptr;
  }

  return device;
}

}  // namespace cecservice
