//
//  AudioBusFormatList.hpp
//  SwitchboardSDK
//
//  Created by Balazs Kiss on 2022. 06. 23..
//  Copyright © 2022. Synervoz Inc. All rights reserved.
//

#pragma once

#include <switchboard/export.h>
#include <switchboard_core/AudioBusFormat.hpp>

#include <vector>

namespace switchboard {

/**
 * AudioBusFormatList abstract superclass.
 * @brief Holds a list of AudioBusList instances.
 * @details Represents formats of AudioBusList instances without the need for the audio data.
 * @see AudioBusFormatArray
 * @see AudioBusFormatVector
 */
struct SWITCHBOARDSDK_EXPORT AudioBusFormatList {
public:
    /**
     * @brief Default constructor for AudioBusFormatList.
     */
    AudioBusFormatList() = default;

    /**
     * @brief Default destructor for AudioBusFormatList.
     */
    virtual ~AudioBusFormatList() = default;

    /**
     * @brief Returns the number of audio bus formats.
     *
     * @returns The number of audio buses.
     */
    virtual uint getNumberOfBuses() const = 0;

    /**
     * @brief Returns the audio bus format for the specified index.
     *
     * @param busIndex The index of the audio bus.
     *
     * @returns The AudioBusFormat for the bus index.
     */
    virtual AudioBusFormat& getBusFormat(const uint busIndex) const = 0;

    /**
     * @brief Makes an audio bus format list equal to another audio bus format list.
     *
     * @param other The other audio bus format list.
     */
    virtual AudioBusFormatList& operator=(const AudioBusFormatList& other) = 0;

    /**
     * @brief Resets all audio bus formats stored in the instance.
     */
    void reset();

    /**
     * @brief Checks whether all audio bus formats are set.
     *
     * @returns True if all audio bus formats are defined, false otherwise.
     */
    bool isSet() const;

    /**
     * @brief Checks whether any of the audio bus formats are set.
     *
     * @returns True if any of the audio bus formats are defined, false otherwise.
     */
    bool isPartlySet() const;

    /**
     * @brief Compares two audio bus format lists.
     *
     * @param other The other AudioBusFormatList instance.
     *
     * @returns True if all audio bus formats match, false otherwise.
     */
    bool operator==(const AudioBusFormatList& other);

    /**
     * @brief Compares two audio bus format lists.
     *
     * @param other The other AudioBusFormatList instance.
     *
     * @returns True if the stored audio bus formats are different, false otherwise.
     */
    bool operator!=(const AudioBusFormatList& other);

    /**
     * @brief Matches all bus formats in an AudioBusFormatList instance.
     * @details Finds the first defined bus format and requires the same bus format for all of the other buses. If none of the bus formats are defined, it returns with false.
     *
     * @param busFormats The bus format list in which the bus formats will be matched.
     *
     * @returns True if the bus formats could be matched successfully, false otherwise.
     */
    static bool matchBusFormats(AudioBusFormatList& busFormats);

    /**
     * @brief Matches all bus formats in two AudioBusFormatList instances.
     * @details Finds the first defined bus format and requires the same bus format for all of the other buses. If none of the bus formats are defined, it returns with false.
     *
     * @param busFormatList1 The first bus format list in which the bus formats will be matched.
     * @param busFormatList2 The second bus format list in which the bus formats will be matched.
     *
     * @returns True if the bus formats could be matched successfully, false otherwise.
     */
    static bool matchBusFormats(AudioBusFormatList& busFormatList1, AudioBusFormatList& busFormatList2);

    /**
     * @brief Returns a string representing the object.
     *
     * @returns A string representing the object.
     */
    std::string toString() const;

    AudioBusFormatList(const AudioBusFormatList&) = delete;
};

}
