///
//
// icey
// Copyright (c) 2005, icey <https://0state.com>
//
// SPDX-License-Identifier: LGPL-2.1+
//
/// @addtogroup av
/// @{


#pragma once


#include "icy/av/format.h"
#include <mutex>
#include <string_view>
#include <vector>


namespace icy {
namespace av {


/// Singleton registry of available media container formats for encoding and decoding
class AV_API FormatRegistry
{
public:
    /// Return the singleton FormatRegistry instance.
    static FormatRegistry& instance();

    FormatRegistry();
    virtual ~FormatRegistry() noexcept;

    /// Return the format with the given display name.
    /// Throws std::runtime_error if no format with that name is registered.
    /// @param name  The display name to look up.
    virtual Format& get(std::string_view name);

    /// Return the format with the given short ID (e.g. "mp4").
    /// Throws std::runtime_error if no format with that ID is registered.
    /// @param id  The short format ID to look up.
    virtual Format& getByID(std::string_view id);

    /// Return the format with the given name, or the default format if not found.
    /// @param name  The display name to look up.
    virtual Format& getOrDefault(std::string_view name);

    /// If a default has been specified it will be
    /// returned, other the format with the highest
    /// priority will take precedence.
    virtual Format& getDefault();

    /// Registers the given media format overriding
    /// existing media formats of the same name.
    virtual void registerFormat(const Format& format);

    /// Unregisters the media format matching the
    /// given name.
    virtual bool unregisterFormat(std::string_view name);

    /// Sets the default fallback media format.
    virtual void setDefault(std::string_view name);

    /// @return True if a format with the given display name is registered.
    /// @param name  The display name to check.
    virtual bool exists(std::string_view name);

    /// Remove all registered formats and clear the default.
    virtual void clear();

    /// @return A snapshot copy of all registered formats.
    virtual FormatList formats() const;

private:
    FormatRegistry(const FormatRegistry&) = delete;
    FormatRegistry& operator=(const FormatRegistry&) = delete;
    FormatRegistry(FormatRegistry&&) = delete;
    FormatRegistry& operator=(FormatRegistry&&) = delete;

    Format& findByName(std::string_view name);  // requires _mutex held
    Format& defaultLocked();                        // requires _mutex held

    FormatList _formats;
    std::string _default;
    mutable std::mutex _mutex;
};


} // namespace av
} // namespace icy


/// @}
