#ifndef KMDEPLOYPARSE_H
#define KMDEPLOYPARSE_H

#include <gio/gio.h>
#include <glib.h>
#include <string.h>

#include <filesystem>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "common/KMConfig.h"
#include "common/KMRemoteSummary.h"
#include "common/kmparseappdata.h"
#include "common/kmvariant.h"

using namespace std;
namespace fs = std::filesystem;

/**
 * @brief parse deploy file
 */
class KMParseDeploy
{
public:
    KMParseDeploy();
    ~KMParseDeploy();

    /* 部署后文件解析接口 */
    bool load(const std::string &deployFilePath);
    GBytes *getDeployData(const string &deployFilePath);
    bool isDeployed(const std::string &ref);

    const char *getStringFromDeployData(GBytes *deployData, const char *key);
    const char *getOriginFromDeployData(GBytes *deployData);
    const char *getCommitFromDeployData(GBytes *deployData);
    GVariant *getMetadataFromDeployData(GBytes *deployData);
    gint32 getVersionFromDeployData(GBytes *deployData);
    guint64 getTimestampFromDeployData(GBytes *deployData);
    const char *getLocaledString(GBytes *deployData, const char *key);
    const char *getAltIdFromDeployData(GBytes *deployData);
    const char *getEolFromDeployData(GBytes *deployData);
    const char *getEolRebaseFromDeployData(GBytes *deployData);
    const char *getPreviousIdsFromDeployData(GBytes *deployData, gsize *length);
    const char *getRuntimeFromDeployData(GBytes *deployData);
    const char *getExtensionOfFromDeployData(GBytes *deployData);
    const char **getSubpathsFromDeployData(GBytes *deployData);
    bool hasSubpathsFromDeployData(GBytes *deployData);
    guint64 getInstalledSizeFromDeployData(GBytes *deployData);
    const char *getAppdataNameFromDeployData(GBytes *deployData);
    const char *getAppdataSummaryFromDeployData(GBytes *deployData);
    const char *getAppdataVersionFromDeployData(GBytes *deployData);
    const char *getAppdataLicenseFromDeployData(GBytes *deployData);
    const char *getAppdataContentRatingTypeFromDeployData(GBytes *deployData);
    GHashTable *getAppdataContentRatingFromDeployData(GBytes *deployData);

    /* 部署文件生成接口 */
    bool saveBytesToFile(GFile *dest, GBytes *bytes, GCancellable *cancellable, GError **error);
    GBytes *deployDataToGBytes(KMCommonRef ref, fs::path commitDataPath, GVariant *commitDataGVariant, GVariant *commitMetadataGVariant, GKeyFile *metadata);

private:
    void addCommitMetadataToDeployData(GVariantDict *metadataDict, GVariant *commitMetadataGVariant);
    void addMetadataToDeployData(GVariantDict *metadataDict, GKeyFile *keyfile);
    void addMetadataToDeployDataWithType(GVariantDict *metadataDict, GKeyFile *keyfile, string baseType);
    void addAppdataToDeployData(GVariantDict *metadataDict, fs::path deployDir, const char *id);
    char *readAppdataXmlFromDeployDir(fs::path deployDir, const char *id);
    void addLocaleMetadataString(GVariantDict *metadataDict, const char *keyname, GHashTable *values);
    GVariant *appdataContentRatingToVariant(const char *contentRatingType, GHashTable *contentRating);
    GBytes *readStream(GInputStream *in, gboolean nullTerminate, GError **error);

private:
    class Private;
    std::shared_ptr<Private> d;
};

#endif // KMDEPLOYPARSE_H