/* common/kmostreemutabletree.cpp
 *
 * Copyright (C) 2023 OpenKylin, Inc
 */

#include "KMOstreeMutableTree.h"

class KMOstreeMutableTree::Private
{
public:
    Private();
    Private(OstreeMutableTree *tree);
    ~Private();

    void clearError()
    {
        if (m_error)
        {
            g_error_free(m_error);
        }
    }

    OstreeMutableTree *m_mutableTree = nullptr;
    GError *m_error = nullptr;
};

KMOstreeMutableTree::Private::Private()
{
    m_mutableTree = ostree_mutable_tree_new();
}

KMOstreeMutableTree::Private::Private(OstreeMutableTree *tree)
{
    m_mutableTree = tree;
}

KMOstreeMutableTree::Private::~Private()
{
    if (m_mutableTree)
    {
        g_object_unref(m_mutableTree);
    }

    clearError();
}

KMOstreeMutableTree::KMOstreeMutableTree()
    : d(std::make_shared<Private>())
{
}

KMOstreeMutableTree::KMOstreeMutableTree(OstreeMutableTree *tree)
    : d(std::make_shared<Private>(tree))
{
}

// 不进行深拷贝
KMOstreeMutableTree::KMOstreeMutableTree(const KMOstreeMutableTree &other)
{
    d = other.d;
}

KMOstreeMutableTree::~KMOstreeMutableTree() { }

// 不进行深拷贝
KMOstreeMutableTree &KMOstreeMutableTree::operator=(const KMOstreeMutableTree &other)
{
    if (this != &other && d->m_mutableTree != other.d->m_mutableTree)
    {
        d = other.d;
    }

    return *this;
}

void KMOstreeMutableTree::setMetadataChecksum(const char *checksum)
{
    ostree_mutable_tree_set_metadata_checksum(d->m_mutableTree, checksum);
}

bool KMOstreeMutableTree::ensureDir(const std::string &name, KMOstreeMutableTree &outSubdir)
{
    d->clearError();
    OstreeMutableTree *mtree = NULL;
    bool ret = ostree_mutable_tree_ensure_dir(d->m_mutableTree, name.c_str(), &mtree, &d->m_error);
    if (ret)
    {
        KMOstreeMutableTree kmtree(mtree);
        outSubdir = kmtree;
    }

    return ret;
}

bool KMOstreeMutableTree::replaceFile(const char *name, const char *checksum)
{
    return ostree_mutable_tree_replace_file(d->m_mutableTree, name, checksum, &d->m_error);
}

std::string KMOstreeMutableTree::errorMessage() const
{
    if (d->m_error)
    {
        return d->m_error->message;
    }
    else
    {
        return "";
    }
}

OstreeMutableTree *KMOstreeMutableTree::get()
{
    return d->m_mutableTree;
}
