/*
    SPDX-FileCopyrightText: 2025 Friedrich W. H. Kossebau <kossebau@kde.org>

    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/

#ifndef KASTEN_BYTEARRAYGZIPSTREAMCOMPRESSOR_HPP
#define KASTEN_BYTEARRAYGZIPSTREAMCOMPRESSOR_HPP

// lib
#include "abstractbytearraystreamcompressor.hpp"
// Qt
#include <QString>
// Std
#include <array>

class KConfigGroup;

namespace Kasten {

class GZipStreamCompressorSettings
{
public:
    enum class StrategyId
    {
        Default = 0,
        Filter = 1,
        HuffmanEncodingOnly = 2,
        RunLengthEncoding = 3,
        FixedHuffmanEncoding = 4,
        _Count,
    };

    static constexpr auto StrategyCount = static_cast<std::size_t>(StrategyId::_Count);
    static const std::array<QString, StrategyCount> strategyConfigValueList;

private:
    static constexpr char CompressionLevelConfigKey[] = "CompressionLevel";
    static constexpr char StrategyConfigKey[] = "Strategy";
    static constexpr char FileNameConfigKey[] = "FileName";
    static constexpr char CommentConfigKey[] = "Comment";

    static constexpr int DefaultCompressionLevel = -1;
    static constexpr StrategyId DefaultStrategy = StrategyId::Default;
    static const QString DefaultFileName;
    static const QString DefaultComment;

public:
    GZipStreamCompressorSettings();
    GZipStreamCompressorSettings(const GZipStreamCompressorSettings&) = default;
    GZipStreamCompressorSettings(GZipStreamCompressorSettings&&) = default;

    ~GZipStreamCompressorSettings() = default;

    GZipStreamCompressorSettings& operator=(const GZipStreamCompressorSettings&) = default;
    GZipStreamCompressorSettings& operator=(GZipStreamCompressorSettings&&) = default;

    [[nodiscard]]
    bool operator==(const GZipStreamCompressorSettings& other) const;

public:
    void loadConfig(const KConfigGroup& configGroup);
    void saveConfig(KConfigGroup& configGroup) const;

public:
    int compressionLevel = DefaultCompressionLevel;
    StrategyId strategyId = DefaultStrategy;
    QString fileName = DefaultFileName;
    QString comment = DefaultComment;
};

class ByteArrayGZipStreamCompressor : public AbstractByteArrayStreamCompressor
{
    Q_OBJECT

private:
    static const QString ConfigGroupId;

public:
    ByteArrayGZipStreamCompressor();
    ~ByteArrayGZipStreamCompressor() override;

public:
    [[nodiscard]]
    GZipStreamCompressorSettings settings() const;
    void setSettings(const GZipStreamCompressorSettings& settings);

protected: // AbstractByteArrayStreamCompressor API
    [[nodiscard]]
    std::unique_ptr<AbstractCompressionStream> createCompressionStream(AbstractByteArrayOutput* byteArrayOutput) override;

private:
    GZipStreamCompressorSettings m_settings;
};

inline GZipStreamCompressorSettings ByteArrayGZipStreamCompressor::settings() const { return m_settings; }

}

#endif
