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

#pragma once

#include <fbl/intrusive_double_list.h>
#include <fbl/intrusive_wavl_tree.h>
#include <fbl/unique_ptr.h>
#include <zircon/hw/usb-audio.h>

#include "usb-audio-descriptors.h"
#include "usb-audio-path.h"
#include "usb-audio-units.h"

namespace audio {
namespace usb {

class UsbAudioDevice;

class UsbAudioControlInterface {
  public:
    // Note that UsbAudioControlInterfaces are entirely owned by UsbAudioDevice
    // instances.  The control interface needs to hold a pointer to its parent,
    // so it is critically important that the owning parent is certain that the
    // control interface (and all of its children) have been properly shut down
    // before exiting.  At all times, the lifetime of the control interface
    // needs to be a subset of the lifetime of the device parent.
    static fbl::unique_ptr<UsbAudioControlInterface> Create(UsbAudioDevice* parent);
    zx_status_t Initialize(DescriptorListMemory::Iterator* iter);

    const char* log_prefix() const;

    // Extract the AudioPath whose streaming terminal interface link ID matches
    // the users request, if any.  Otherwise, simply return nullptr.
    fbl::unique_ptr<AudioPath> ExtractPath(uint8_t term_link, Direction direction) {
        return paths_.erase_if(
            [term_link, direction](const AudioPath& path) -> bool {
                return (path.stream_terminal().id() == term_link) &&
                       (path.direction() == direction);
            });
    }


  private:
    friend class fbl::unique_ptr<UsbAudioControlInterface>;
    using UnitMap = fbl::WAVLTree<uint32_t, fbl::RefPtr<AudioUnit>>;

    UsbAudioControlInterface(UsbAudioDevice* parent);
    ~UsbAudioControlInterface();

    // A recursive method used to find interesting audio paths in the
    // unit/terminal graph.  See the comment at the end of the Init
    // implementation for details about the algorithm used to find these paths.
    fbl::unique_ptr<AudioPath> TracePath(const OutputTerminal& out_term,
                                         const UnitMap::iterator& current,
                                         uint32_t level = 0);

    // The reference to our parent.  Note, because of this unmanaged reference,
    // it is critically important that the surrounding code ensure that we never
    // outlive our parent device.
    UsbAudioDevice& parent_;

    // Cached, unmanaged pointers to our interface and class descriptors.  The
    // memory which backs these descriptors is kept alive by the top level
    // desc_list_ reference.
    //
    // TODO(johngro) : this desc_list_ memory is contained in our parent
    // UsbAudioDevice.  Since we have already commited to having a lifetime
    // which is strictly <= the lifetime of our parent, we should probably just
    // access the descriptor memory using our parent instead of holding our own
    // reference to it.
    fbl::RefPtr<DescriptorListMemory> desc_list_;
    const usb_interface_descriptor_t* interface_hdr_ = nullptr;
    const usb_audio_ac_header_desc* class_hdr_ = nullptr;

    // All unit/terminal IDs for a given Audio Control Interface
    //
    // TODO(johngro): Strictly speaking, we don't really need to hold onto this.
    // If we wanted, we could just keep this as a local variable used during
    // Init and discard it afterwards.
    UnitMap units_;

    // The complete set of valid paths we have discovered.
    fbl::DoublyLinkedList<fbl::unique_ptr<AudioPath>> paths_;
};

}  // namespace usb
}  // namespace audio
