/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <iostream>
#include <vector>

#include "avrcp_packet.h"

// These classes are temporary placeholders to easily switch between BT_HDR and
// packets.
class VectorPacket : public ::bluetooth::Packet {
 public:
  using Packet::Packet;  // Inherit constructors

  static std::shared_ptr<VectorPacket> Make() {
    return std::shared_ptr<VectorPacket>(new VectorPacket());
  };

  static std::shared_ptr<VectorPacket> Make(std::vector<uint8_t> payload) {
    auto pkt = VectorPacket::Make();
    pkt->packet_start_index_ = 0;
    pkt->packet_end_index_ = payload.size();
    pkt->data_ = std::make_shared<std::vector<uint8_t>>(std::move(payload));
    return pkt;
  };

  const std::vector<uint8_t>& GetData() { return *data_; };

  virtual std::string ToString() const {
    std::stringstream ss;
    ss << "VectorPacket:" << std::endl;
    ss << "  └ Payload =";
    for (auto it = begin(); it != end(); it++) {
      ss << " " << loghex(*it);
    }
    ss << std::endl;

    return ss.str();
  };

  virtual std::pair<size_t, size_t> GetPayloadIndecies() const override {
    return std::pair<size_t, size_t>(packet_start_index_, packet_end_index_);
  }

  virtual bool IsValid() const override { return true; }
};

// TODO (apanicke): When deleting the old AVRCP Stack, remove this class and
// instead create a BT_HDR Parsing packet.
class AvrcpMessageConverter {
 public:
  static std::shared_ptr<::bluetooth::Packet> Parse(tAVRC_MSG* m) {
    std::vector<uint8_t> data;

    switch (m->hdr.opcode) {
      case AVRC_OP_VENDOR: {
        tAVRC_MSG_VENDOR* msg = (tAVRC_MSG_VENDOR*)m;
        data.push_back(m->hdr.ctype);
        data.push_back((m->hdr.subunit_type << 3) | m->hdr.subunit_id);
        data.push_back(m->hdr.opcode);
        for (int i = 2; i >= 0; i--) {
          data.push_back((uint8_t)((msg->company_id >> i * 8) & 0xff));
        }
        for (uint8_t i = 0; i < msg->vendor_len; i++) {
          data.push_back(msg->p_vendor_data[i]);
        }
      } break;
      case AVRC_OP_PASS_THRU: {
        tAVRC_MSG_PASS* msg = (tAVRC_MSG_PASS*)m;
        data.push_back(m->hdr.ctype);
        data.push_back((m->hdr.subunit_type << 3) | m->hdr.subunit_id);
        data.push_back(m->hdr.opcode);
        data.push_back((msg->state << 7) | msg->op_id);
        data.push_back(0x00);
      } break;
      case AVRC_OP_BROWSE: {
        tAVRC_MSG_BROWSE* msg = (tAVRC_MSG_BROWSE*)m;
        // The first 3 bytes are header bytes that aren't actually in AVRCP
        // packets
        for (int i = 0; i < msg->browse_len; i++) {
          data.push_back(msg->p_browse_data[i]);
        }
      } break;
      default:
        LOG(ERROR) << "Unknown opcode for AVRCP message";
        break;
    }

    return VectorPacket::Make(data);
  }
};