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

#include "packet_stream.h"
#include "command_packet.h"
#include "event_packet.h"
#include "packet.h"

#include <gtest/gtest.h>
#include <cstdint>
#include <memory>
#include <vector>
using std::vector;

#include "hci/include/hci_hal.h"
#include "stack/include/hcidefs.h"

#include <sys/socket.h>

namespace {
const char small_payload[] = "foo bar baz";
const char large_payload[] =
    "Aristotle's principles will then be no more principles to him, than those "
    "of Epicurus and the Stoics: let this diversity of opinions be propounded "
    "to, and laid before him; he will himself choose, if he be able; if not, "
    "he will remain in doubt.";
}  // namespace

namespace test_vendor_lib {

class PacketStreamTest : public ::testing::Test {
 public:
  PacketStreamTest() {
    socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds_);
    CheckSocketpairInit();
  }

  ~PacketStreamTest() {
    close(socketpair_fds_[0]);
    close(socketpair_fds_[1]);
  }

  void CheckedReceiveCommand(const char* payload, uint16_t opcode) {
    uint8_t payload_size = strlen(payload);
    vector<uint8_t> packet;

    packet.push_back(DATA_TYPE_COMMAND);
    packet.push_back(opcode);
    packet.push_back(opcode >> 8);
    packet.push_back(payload_size);

    // Set the packet's payload.
    for (int i = 0; i < payload_size; ++i) packet.push_back(payload[i]);

    // Send the packet to |packet_stream_|.
    write(socketpair_fds_[1], &packet[1], packet.size());

    // Read the command packet.
    std::unique_ptr<CommandPacket> command = packet_stream_.ReceiveCommand(socketpair_fds_[0]);

    const vector<uint8_t> received_payload = command->GetPayload();

    // Validate the packet by checking that it's the appropriate size and then
    // checking each byte.
    EXPECT_EQ(packet.size(), command->GetPacketSize());
    EXPECT_EQ(DATA_TYPE_COMMAND, command->GetType());
    EXPECT_EQ(opcode, command->GetOpcode());
    EXPECT_EQ(static_cast<size_t>(payload_size + 1), command->GetPayloadSize());
    EXPECT_EQ(payload_size, received_payload[0]);
    for (int i = 0; i < payload_size; ++i) EXPECT_EQ(packet[4 + i], received_payload[i + 1]);
  }

  void CheckedSendEvent(std::unique_ptr<EventPacket> event) {
    const vector<uint8_t> expected_payload = event->GetPayload();
    auto expected_size = event->GetPacketSize();
    auto expected_code = event->GetEventCode();
    auto expected_payload_size = event->GetPayloadSize();

    EXPECT_TRUE(packet_stream_.SendEvent(std::move(event), socketpair_fds_[0]));

    // Read the packet sent by |packet_stream_|.
    uint8_t event_header[2];
    read(socketpair_fds_[1], event_header, 2);

    uint8_t return_parameters_size;
    read(socketpair_fds_[1], &return_parameters_size, 1);

    uint8_t return_parameters[return_parameters_size];
    read(socketpair_fds_[1], return_parameters, sizeof(return_parameters));

    // Validate the packet by checking that it's the
    // appropriate size and then checking each byte.
    EXPECT_EQ(expected_size, sizeof(event_header) + return_parameters_size + 1);
    EXPECT_EQ(DATA_TYPE_EVENT, event_header[0]);
    EXPECT_EQ(expected_code, event_header[1]);
    EXPECT_EQ(expected_payload_size, static_cast<size_t>(return_parameters_size) + 1);
    for (int i = 0; i < return_parameters_size; ++i) EXPECT_EQ(expected_payload[i + 1], return_parameters[i]);
  }

 protected:
  PacketStream packet_stream_;

  int socketpair_fds_[2];

 private:
  // Workaround because ASSERT cannot be used directly in a constructor
  void CheckSocketpairInit() {
    ASSERT_TRUE(socketpair_fds_[0] > 0);
    ASSERT_TRUE(socketpair_fds_[1] > 0);
  }
};

TEST_F(PacketStreamTest, ReceivePacketType) {
  serial_data_type_t command_type = DATA_TYPE_COMMAND;
  write(socketpair_fds_[1], &command_type, 1);
  EXPECT_EQ(command_type, packet_stream_.ReceivePacketType(socketpair_fds_[0]));
}

TEST_F(PacketStreamTest, ReceiveEmptyCommand) {
  CheckedReceiveCommand("", HCI_RESET);
}

TEST_F(PacketStreamTest, ReceiveSmallCommand) {
  CheckedReceiveCommand(small_payload, HCI_RESET);
}

TEST_F(PacketStreamTest, ReceiveLargeCommand) {
  CheckedReceiveCommand(large_payload, HCI_RESET);
}

TEST_F(PacketStreamTest, SendEvent) {
  const vector<uint8_t> return_parameters = {0};
  CheckedSendEvent(EventPacket::CreateCommandCompleteEvent(HCI_RESET, return_parameters));
}

}  // namespace test_vendor_lib
