// Copyright 2019 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/sim-nvm.h"

#include <string.h>
#include <zircon/assert.h>

#include <vector>

extern "C" {
#include "third_party/iwlwifi/fw/api/nvm-reg.h"
#include "third_party/iwlwifi/mvm/mvm.h"
}

#include "third_party/iwlwifi/test/sim-nvm-data.inc"

namespace wlan::testing {

std::vector<uint8_t> SimNvm::HandleChunkRead(uint8_t target, uint16_t type, uint16_t offset,
                                             uint16_t length) {
  auto sections = GetDefaultNvmSections();
  for (auto iter : sections) {
    if (iter.target != target || iter.type != type) {
      continue;
    }

    // Offsetting a null pointer is undefined behavior, even if the offset is zero. Passing a null
    // pointer to memcpy (or any similar function) is also undefined behavior.
    if (iter.data.data() == nullptr) {
      // There is no other <target, type> pair existing so that we can have early return. See the
      // comment of GetDefaultNvmSections().
      return {};
    }

    // Handle the boundary cases.
    size_t size = iter.data.size();
    if (offset > size) {
      offset = size;
    }
    if (offset + length > size) {
      length = size - offset;
    }

    std::vector<uint8_t> ret;
    ret.reserve(length);
    std::copy_n(iter.data.begin() + offset, length, std::back_inserter(ret));
    return ret;
  }

  return {};  // No segment found.
}

zx_status_t SimNvm::HandleCommand(struct iwl_host_cmd* cmd, SimMvmResponse* resp) {
  // Currently we only support the first data segment.
  ZX_ASSERT(!cmd->data[1]);

  const struct iwl_nvm_access_cmd* nvm_access_cmd =
      reinterpret_cast<const struct iwl_nvm_access_cmd*>(cmd->data[0]);
  uint8_t target = nvm_access_cmd->target;
  uint16_t type = le16_to_cpu(nvm_access_cmd->type);
  uint16_t offset = le16_to_cpu(nvm_access_cmd->offset);
  uint16_t length = le16_to_cpu(nvm_access_cmd->length);

  switch (nvm_access_cmd->op_code) {
    case NVM_READ_OPCODE: {
      std::vector<uint8_t> payload = HandleChunkRead(target, type, offset, length);
      resp->resize(sizeof(struct iwl_nvm_access_resp) + payload.size());
      struct iwl_nvm_access_resp* nvm_resp =
          reinterpret_cast<struct iwl_nvm_access_resp*>(resp->data());
      nvm_resp->offset = cpu_to_le16(offset);
      nvm_resp->type = cpu_to_le16(type);
      nvm_resp->status = cpu_to_le16(READ_NVM_CHUNK_SUCCEED);
      nvm_resp->length = cpu_to_le16(payload.size());
      memcpy(nvm_resp->data, payload.data(), payload.size());
      return ZX_OK;
    }

    default:
      return ZX_ERR_NOT_SUPPORTED;
  }
}

}  // namespace wlan::testing
