// 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.

#ifndef HERMES_CARD_QRTR_H_
#define HERMES_CARD_QRTR_H_

#include <deque>
#include <iostream>
#include <memory>
#include <vector>

#include <google-lpa/lpa/card/euicc_card.h>
#include <libqrtr.h>

#include "hermes/executor.h"
#include "hermes/logger.h"
#include "hermes/qmi_uim.h"
#include "hermes/socket_qrtr.h"

namespace hermes {

// Implementation of EuiccCard using QRTR sockets to send QMI UIM
// messages.
class CardQrtr : public lpa::card::EuiccCard {
 public:
  // Base class for the tx info specific to a certain type of uim command.
  // Uim command types that need any additional information should define
  // a child class. An instance of that class should be set to the data pointer
  // in its corresponding TxElement.
  struct TxInfo {
    virtual ~TxInfo() = default;
  };

  using ResponseCallback = std::function<void(
      std::vector<std::vector<uint8_t>>& responses, int err)>;

  static std::unique_ptr<CardQrtr> Create(
      std::unique_ptr<SocketInterface> socket,
      Logger* logger,
      Executor* executor);
  virtual ~CardQrtr();

  // lpa::card::EuiccCard overrides.
  void SendApdus(std::vector<lpa::card::Apdu> apdus,
                 ResponseCallback cb) override;
  lpa::util::EuiccLog* logger() override { return logger_; }

 private:
  struct TxElement {
    std::unique_ptr<TxInfo> info_;
    uint16_t id_;
    QmiUimCommand uim_type_;
  };

  CardQrtr(std::unique_ptr<SocketInterface> socket,
           Logger* logger,
           Executor* executor);
  void Initialize();
  void FinalizeInitialization();
  void Shutdown();
  uint16_t AllocateId();

  // Top-level method to transmit an element from the tx queue. Dispatches to
  // the proper TransmitQmi* method to perform QMI encoding prior to sending
  // data to the socket. Will remove elements from the tx queue as needed.
  void TransmitFromQueue();
  // Creates and sends RESET QMI request.
  void TransmitQmiReset(TxElement* tx_element);
  // Creates and sends OPEN_LOGICAL_CHANNEL QMI request.
  void TransmitQmiOpenLogicalChannel(TxElement* tx_element);
  // Creates and sends SEND_APDU QMI request.
  void TransmitQmiSendApdu(TxElement* tx_element);
  // Performs QMI encoding and sends data to the QRTR socket.
  bool SendCommand(QmiUimCommand type,
                   uint16_t id,
                   void* c_struct,
                   qmi_elem_info* ei);

  // Top-level method when a packet is read from the socket into |buffer_|. Will
  // perform proper processing based on QRTR packet type. Attempts to transmit
  // the next element in the tx queue when complete.
  void ProcessQrtrPacket(uint32_t node, uint32_t port, int size);
  // Dispatches to proper ReceiveQmi* method based on QMI type.
  void ProcessQmiPacket(const qrtr_packet& packet);
  // Performs decoding for OPEN_LOGICAL_CHANNEL QMI response.
  void ReceiveQmiOpenLogicalChannel(const qrtr_packet& packet);
  // Performs decoding for SEND_APDU response and calls |on_recv_| with
  // appropriate parameters.
  void ReceiveQmiSendApdu(const qrtr_packet& packet);

  void OnDataAvailable(SocketInterface* socket);

  // lpa::card::EuiccCard overrides.
  const lpa::proto::EuiccSpecVersion& GetCardVersion() override;
  lpa::util::Executor* executor() override { return executor_; }

 private:
  friend class CardQrtrTest;

  ///////////////////
  // State Diagram //
  ///////////////////
  //
  //       [Start state]
  //     +---------------+  (FinalizeInitialization() called w/failure)
  //     | Uninitialized | <--------------------------------------------+
  //     +---------------+                                              |
  //             +                                                      |
  //             | (Initialize() called)                                |
  //             |                                                      |
  //             V                                                      |
  //    +-------------------+     +------------+                        |
  //    | InitializeStarted | +-> | UimStarted | +---+                  |
  //    +-------------------+     +------------+     |                  |
  //                                                 |                  |
  //              +----------------------------------+                  |
  //              |                                                     |
  //              V                                                     |
  //   +-----------------------+     +----------------------+           |
  //   | LogicalChannelPending | +-> | LogicalChannelOpened | +---------+
  //   +-----------------------+     +----------------------+           |
  //                                                                    |
  //             +------------------------------------------------------+
  //             |     (FinalizeInitialization() called w/success)
  //             V
  //         +-------+
  //         | Ready | <--------------------+
  //         +-------+                      |
  //             +                          |
  //             | (Request sent)           | (Response received)
  //             |                          |
  //             V                          |
  //   +--------------------+               |
  //   | WaitingForResponse | +-------------+
  //   +--------------------+
  //
  class State {
   public:
    enum Value : uint8_t {
      kUninitialized,
      kInitializeStarted,
      kUimStarted,
      kLogicalChannelPending,
      kLogicalChannelOpened,
      kReady,
      kWaitingForResponse,
    };

    State() : value_(kUninitialized) {}
    // Transitions to the indicated state. Returns whether or not the transition
    // was successful.
    bool Transition(Value value);

    bool IsInitialized() const {
      return value_ == kReady || value_ == kWaitingForResponse;
    }
    // Returns whether or not some QMI packet can be sent out in the state. Note
    // that APDUs in particular may only be sent in the kReady state.
    bool CanSend() const { return value_ == kUimStarted || value_ == kReady; }

    bool operator==(Value value) const { return value_ == value; }
    bool operator!=(Value value) const { return value_ != value; }
    friend std::ostream& operator<<(std::ostream& os, const State state) {
      os << state.value_;
      return os;
    }

   private:
    explicit State(Value value) : value_(value) {}

    Value value_;
  };

  State current_state_;

  bool extended_apdu_supported_;
  uint16_t current_transaction_id_;

  // Logical Channel that will be used to communicate with the chip, returned
  // from OPEN_LOGICAL_CHANNEL request sent once the QRTR socket has been
  // opened.
  uint8_t channel_;
  // The slot that the logical channel to the eSIM will be made. Initialized in
  // constructor, hardware specific.
  uint8_t slot_;

  std::unique_ptr<SocketInterface> socket_;
  SocketQrtr::PacketMetadata metadata_;

  // Buffer for storing data from the QRTR socket
  std::vector<uint8_t> buffer_;
  // List of responses for the oldest SendApdus call that hasn't been completely
  // processed.
  std::vector<std::vector<uint8_t>> responses_;
  // Queue of packets to send to the modem
  std::deque<TxElement> tx_queue_;

  Logger* logger_;
  Executor* executor_;
  lpa::proto::EuiccSpecVersion spec_version_;
};

}  // namespace hermes

#endif  // HERMES_CARD_QRTR_H_
