// 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,  // NOLINT(runtime/references)
                         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;
  bool IsSimValidAfterEnable() override;
  bool IsSimValidAfterDisable() 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_
