// Copyright 2018 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 <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <pretty/hexdump.h>

#include <utility>

#include "debug-logging.h"
#include "usb-audio-descriptors.h"

namespace audio {
namespace usb {

DescriptorListMemory::~DescriptorListMemory() {
    // According to docs in the header, data allocated using
    // usb_get_descriptor_list should be free'ed using a standard C "free"
    if (data_ != nullptr) {
        free(data_);
    }
}

fbl::RefPtr<DescriptorListMemory> DescriptorListMemory::Create(usb_protocol_t* proto) {
    ZX_DEBUG_ASSERT(proto != nullptr);

    fbl::AllocChecker ac;
    auto ret = fbl::AdoptRef(new (&ac) DescriptorListMemory());
    if (!ac.check()) {
        GLOBAL_LOG(ERROR, "Failed to allocate descriptor list memory!");
        return nullptr;
    }

    size_t desc_length = usb_get_descriptors_length(proto);
    ret->data_ = malloc(desc_length);
    if (!ret->data_) {
        return nullptr;
    }
    usb_get_descriptors(proto, ret->data_, desc_length, &ret->size_);

    if (zxlog_level_enabled(SPEW)) {
        GLOBAL_LOG(SPEW, "Descriptor List is %zu bytes long\n", ret->size_);
        hexdump8_ex(ret->data_, ret->size_, 0u);
    }

    return ret;
}

DescriptorListMemory::Iterator::Iterator(fbl::RefPtr<DescriptorListMemory> mem)
    : mem_(std::move(mem)) {
    ZX_DEBUG_ASSERT(mem_ != nullptr);
    // Make sure our offset is valid, or go ahead and invalidate it right from
    // the start.
    ValidateOffset();
}

bool DescriptorListMemory::Iterator::Next() {
    auto h = hdr();

    // Have we already run out of headers?
    if (h == nullptr) {
        return false;
    }

    // Advance to the next header, then validate our offset.  Note that there is
    // no overflow check here.  If we overflow a 64 bit size_t, the implication
    // is that we are holding a USB descriptor list in RAM whose size is within
    // 256 bytes of our entire 64 bit address space.  This really should be
    // impossible, so we don't bother to check.
    offset_ += h->bLength;
    return ValidateOffset();
}

bool DescriptorListMemory::Iterator::ValidateOffset() {
    ZX_DEBUG_ASSERT(offset_ <= mem_->size());
    size_t space = mem_->size() - offset_;

    if (!space) {
        return false;
    }

    // If anything goes wrong from here on out, make sure to invalidate our offset.
    auto cleanup = fbl::MakeAutoCall([this] { offset_ = mem_->size(); });

    if (space < sizeof(usb_descriptor_header_t)) {
        GLOBAL_LOG(WARN,
                   "Insufficient space at offset %zu to contain even the most basic USB descriptor "
                   "(space needed %zu, space left %zu)\n",
                   offset_, sizeof(usb_descriptor_header_t), space);
        return false;
    }

    auto tmp = reinterpret_cast<uintptr_t>(mem_->data());
    auto h = reinterpret_cast<const usb_descriptor_header_t*>(tmp + offset_);
    if (h->bLength > space) {
        GLOBAL_LOG(WARN,
                   "Malformed USB descriptor header (type %u) at offset %zu.  "
                   "Header indicates that it is %u bytes long, but there %zu bytes remaining\n",
                   h->bDescriptorType,
                   offset_,
                   h->bLength,
                   space);
        return false;
    }

    GLOBAL_LOG(SPEW, "Found Descriptor [type 0x%02x, len 0x%02x] at offset 0x%zx/0x%zx\n",
            h->bDescriptorType, h->bLength, offset_, mem_->size());

    cleanup.cancel();
    return true;
}

}  // namespace usb
}  // namespace audio
