// Copyright 2021 The Fuchsia 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 "third_party/iwlwifi/test/wlan-pkt-builder.h"

#include <fuchsia/wlan/common/cpp/banjo.h>

#include <cstring>

#include <zxtest/zxtest.h>

namespace wlan::testing {

WlanPktBuilder::WlanPkt::WlanPkt(const uint8_t* buf, size_t len)
    : mac_pkt_(std::make_unique<ieee80211_mac_packet>()),
      wlan_pkt_(std::make_unique<wlan_tx_packet_t>()),
      buf_(new uint8_t[len]),
      len_(len) {
  ASSERT_NOT_NULL(mac_pkt_);
  ASSERT_NOT_NULL(wlan_pkt_);
  ASSERT_NOT_NULL(buf_);
  std::memcpy(&*buf_, buf, len);

  *mac_pkt_ = {};
  mac_pkt_->common_header = reinterpret_cast<ieee80211_frame_header*>(&*buf_);
  mac_pkt_->header_size = ieee80211_get_header_len(mac_pkt_->common_header);
  mac_pkt_->body = &*buf_ + mac_pkt_->header_size;
  mac_pkt_->body_size = len - mac_pkt_->header_size;

  *wlan_pkt_ = {};
  wlan_pkt_->packet_head.data_buffer = &*buf_;
  wlan_pkt_->packet_head.data_size = len;
  wlan_pkt_->info.tx_flags = 0;
  wlan_pkt_->info.channel_bandwidth = CHANNEL_BANDWIDTH_CBW20;
}

WlanPktBuilder::WlanPkt::~WlanPkt() = default;

ieee80211_mac_packet* WlanPktBuilder::WlanPkt::mac_pkt() { return mac_pkt_.get(); }

const ieee80211_mac_packet* WlanPktBuilder::WlanPkt::mac_pkt() const { return mac_pkt_.get(); }

wlan_tx_packet_t* WlanPktBuilder::WlanPkt::wlan_pkt() { return wlan_pkt_.get(); }

const wlan_tx_packet_t* WlanPktBuilder::WlanPkt::wlan_pkt() const { return wlan_pkt_.get(); }

size_t WlanPktBuilder::WlanPkt::len() const { return len_; }

WlanPktBuilder::WlanPktBuilder() = default;

WlanPktBuilder::~WlanPktBuilder() = default;

std::shared_ptr<WlanPktBuilder::WlanPkt> WlanPktBuilder::build() {
  static constexpr uint8_t kMacPkt[] = {
      0x08, 0x01,                          // frame_ctrl
      0x00, 0x00,                          // duration
      0x11, 0x22, 0x33, 0x44, 0x55, 0x66,  // MAC1
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // MAC2
      0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // MAC3
      0x00, 0x00,                          // seq_ctrl
      0x45, 0x00, 0x55, 0x66, 0x01, 0x83,  // random IP packet...
  };

  std::shared_ptr<WlanPkt> wlan_pkt(new WlanPkt(kMacPkt, sizeof(kMacPkt)));
  ZX_ASSERT(wlan_pkt);
  return wlan_pkt;
}

}  // namespace wlan::testing
