// 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/auto_call.h>

#include <utility>

#include "debug-logging.h"
#include "usb-audio-control-interface.h"
#include "usb-audio-device.h"
#include "usb-audio-units.h"

namespace audio {
namespace usb {

// We use our parent's log prefix
const char* UsbAudioControlInterface::log_prefix() const {
    return parent_.log_prefix();
}

UsbAudioControlInterface::UsbAudioControlInterface(UsbAudioDevice* parent)
    : parent_(*parent) {
    ZX_DEBUG_ASSERT(parent != nullptr);
}

UsbAudioControlInterface::~UsbAudioControlInterface() {
}

fbl::unique_ptr<UsbAudioControlInterface> UsbAudioControlInterface::Create(UsbAudioDevice* parent) {
    if (parent == nullptr) {
        GLOBAL_LOG(ERROR, "null parent passed to %s\n", __PRETTY_FUNCTION__);
        return nullptr;
    }

    fbl::AllocChecker ac;
    fbl::unique_ptr<UsbAudioControlInterface> ret(new (&ac) UsbAudioControlInterface(parent));
    if (ac.check()) {
        return ret;
    }

    return nullptr;
}

zx_status_t UsbAudioControlInterface::Initialize(DescriptorListMemory::Iterator* iter) {
    ZX_DEBUG_ASSERT(iter != nullptr);
    ZX_DEBUG_ASSERT(iter->desc_list() != nullptr);

    // It is an error to attempt to initialize this class twice.
    if (desc_list_ != nullptr) {
        LOG(ERROR, "Attempted to initialize control interface twice\n");
        return ZX_ERR_BAD_STATE;
    }

    desc_list_ = iter->desc_list();
    interface_hdr_ = iter->hdr_as<usb_interface_descriptor_t>();

    // These should already have been checked before Initialize was called.
    ZX_DEBUG_ASSERT(interface_hdr_ != nullptr);
    ZX_DEBUG_ASSERT(interface_hdr_->bInterfaceClass == USB_CLASS_AUDIO);
    ZX_DEBUG_ASSERT(interface_hdr_->bInterfaceSubClass == USB_SUBCLASS_AUDIO_CONTROL);

    // Parse all of the descriptors which belong to this audio control
    // interface.  As soon as we find something which does not belong to the
    // interface, break out of the parse loop, leaving the iterator pointing at
    // the next descriptor (if any).  Then try to make sense of the descriptors
    // we did find.
    while (iter->Next()) {
        {
            auto hdr = iter->hdr();
            if (!hdr || (hdr->bDescriptorType != USB_AUDIO_CS_INTERFACE)) {
                break;
            }
        }

        auto hdr = iter->hdr_as<usb_audio_desc_header>();
        if (!hdr) {
            LOG(WARN, "Badly formed audio control descriptor header @ offset %zu\n",
                iter->offset());
            continue;
        }

        if (hdr->bDescriptorSubtype == USB_AUDIO_AC_HEADER) {
            if (class_hdr_ == nullptr) {
                class_hdr_ = iter->hdr_as<usb_audio_ac_header_desc>();
                if (class_hdr_ == nullptr) {
                    LOG(WARN, "Badly formed audio control class specific header @ offset %zu\n",
                        iter->offset());
                }
            } else {
                LOG(WARN, "Duplicate audio control class specific header @ offset %zu\n",
                    iter->offset());
            }

            continue;
        }

        auto unit = AudioUnit::Create(*iter, interface_hdr_->bInterfaceNumber);
        if (unit == nullptr) {
            LOG(WARN, "Failed to create audio Terminal/Unit (type %u) @ offset %zu\n",
                hdr->bDescriptorSubtype, iter->offset());
        } else {
            // Add our new unit to the collection we are building up.  There
            // should be no collision; all unit IDs are supposed to be
            // unique within a given control interface.  If we encounter a
            // collision, log a warning and move on (eg, just try to do the
            // best we can).
            uint32_t id = unit->id();
            if (!units_.insert_or_find(std::move(unit))) {
                LOG(WARN, "Collision when attempting to add unit id %u; skipping this unit\n", id);
            }
        }
    }

    // Next, give each Unit/Terminal a chance to probe any state they will need
    // to operate which will require performing actual USB transactions.
    for (auto& unit : units_) {
        zx_status_t res = unit.Probe(parent_.usb_proto());
        if (res != ZX_OK) {
            LOG(ERROR, "Failed to probe %s (id %u) during initialization!\n",
                unit.type_name(), unit.id());
            return res;
        }
    }

    // OK - now that we have our set of descriptors, attempt to find the audio
    // paths through this graph that we intend to publish.  The algorithm used
    // here is not particularly sophisticated.  Basically, we are going to start
    // at each output terminal in the set and attempt to trace our way back to
    // an input terminal that forms a path from host to pin (or vice versa).
    // Pin-to-pin or host-to-host paths are ignored, although if we someday want
    // to recognize sidetone paths, we should probably pay some attention to the
    // pin to pin paths.
    //
    // We explore the graph using a depth first recursive search using a state
    // bit stored in the terminal/unit classes to avoid cycles.  Since the unit
    // IDs used by terminal/units are 8-bits, we can only recurse an absolute
    // maximum of 256 times, which should be safe from stack overflow for the
    // class of hardware this driver is intended for.
    //
    // Once any valid path from output to input has been found, we stop the
    // search, even if there may be another path to consider.  For most simple
    // devices out there, this should be sufficient, however as time goes on we
    // may discover more complicated devices that will require us to revisit
    // this algorithm and make it a bit smarter.  Failing that, a custom driver
    // would be needed for these more complicated hypothetical devices.
    for (auto iter = units_.begin(); iter.IsValid(); ++iter) {
        // We are only interested in output terminals.  Skip all of the rest.
        if (iter->type() != AudioUnit::Type::OutputTerminal) {
            continue;
        }

        // Do the search.  If it succeed, we will get a reference to an
        // AudioPath object back.
        LOG(TRACE, "Beginning trace for Output Terminal id %u\n", iter->id());
        auto path = TracePath(static_cast<const OutputTerminal&>(*iter), iter);
        if (path != nullptr) {
            LOG(TRACE, "Found valid path!\n");

            zx_status_t status = path->Setup(parent_.usb_proto());
            if (status != ZX_OK) {
                LOG(TRACE, "Failed to setup path! (status %d)\n", status);
            } else {
                paths_.push_back(std::move(path));
            }
        } else {
            LOG(TRACE, "No valid path found\n");
        }
    }

    // Now that we have found all of our valid paths, go over our list of
    // discovered units and mute any volume controls in feature units which are
    // not currently being used by any audio paths.
    for (auto& unit : units_) {
        if ((unit.type() == AudioUnit::Type::FeatureUnit) && !unit.in_use()) {
            auto& feature_unit = static_cast<FeatureUnit&>(unit);
            feature_unit.SetMute(parent_.usb_proto(), true);
        }

        // TODO(johngro) : If we encounter un-used mixer nodes, we should set
        // all of their inputs to maximum dB down in an attempt to effectively
        // mute them.
    }

    return ZX_OK;
}

fbl::unique_ptr<AudioPath> UsbAudioControlInterface::TracePath(const OutputTerminal& out_term,
                                                               const UnitMap::iterator& current,
                                                               uint32_t level) {
    // Flag the current node as having been visited and setup a cleanup task to
    // clear the flag as we unwind.
    auto cleanup = fbl::MakeAutoCall([&current]() { current->visited() = false; });
    ZX_DEBUG_ASSERT(!current->visited());
    current->visited() = true;
    LOG(TRACE, "Visiting unit id %u, type %s\n", current->id(), current->type_name());

    // If we have reached an input terminal, then check to see if it is of the
    // proper type.  If so, create a new path object and start to unwind the
    // stack, stashing the references to the unit which define the path in the
    // process.  Otherwise, this is a dead end.  Just return null and keep
    // looking.
    if (current->type() == AudioUnit::Type::InputTerminal) {
        // We have found a valid path of one of these terminals is a USB stream
        // terminal, while the other terminal is anything which is not a USB
        // terminal (stream or otherwise).
        const auto& in_term = static_cast<const InputTerminal&>(*current);
        if ((out_term.is_stream_terminal() && !in_term.is_usb_terminal()) ||
           (!out_term.is_stream_terminal() &&  in_term.is_usb_terminal())) {
            auto ret = AudioPath::Create(level + 1);
            if (ret != nullptr) {
                ret->AddUnit(level, current.CopyPointer());
            }
            return ret;
        }

        LOG(TRACE, "Skipping incompatible input terminal (in type 0x%04hx, out type 0x%04hx)\n",
            in_term.terminal_type(), out_term.terminal_type());
        return nullptr;
    }

    for (uint32_t i = 0; i < current->source_count(); ++i) {
        uint32_t source_id = current->source_id(i);
        auto next = units_.find(source_id);
        if (!next.IsValid()) {
            LOG(WARN, "Can't find upstream unit id %u while tracing from unit id %u.\n",
                source_id, current->id());
            continue;
        }

        if (next->visited()) {
            LOG(TRACE, "Skipping already visited unit id %u while tracing from unit id %u\n",
                source_id, current->id());
            continue;
        }

        // Recurse down this path.  If it finds a valid path, stash ourselves in
        // the path and unwind.
        auto path = TracePath(out_term, next, level + 1);
        if (path != nullptr) {
            path->AddUnit(level, current.CopyPointer());
            return path;
        }
    }

    return nullptr;
}

}  // namespace usb
}  // namespace audio
