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

#include "KMOstreeRepoFile.h"

#include <glib.h>

#include <iostream>

class KMOstreeRepoFile::Private
{
public:
    Private(OstreeRepoFile *file, bool needFree = true);
    ~Private();

    OstreeRepoFile *m_file = nullptr;
    bool m_needFree;
};

KMOstreeRepoFile::Private::Private(OstreeRepoFile *file, bool needFree)
{
    m_file = file;
    m_needFree = needFree;
}

KMOstreeRepoFile::Private::~Private()
{
    if (m_needFree && m_file)
    {
        g_object_unref(m_file);
    }
}

KMOstreeRepoFile::KMOstreeRepoFile() { }

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

KMOstreeRepoFile::KMOstreeRepoFile(KMOstreeRepoFile &&other)
{
    d = other.d;
}

KMOstreeRepoFile::KMOstreeRepoFile(KMFile &file)
{
    if (file)
    {
        OstreeRepoFile *ostreeRepoFile = OSTREE_REPO_FILE(file.get());
        if (ostreeRepoFile)
        {
            g_object_ref(ostreeRepoFile);
            d = std::make_shared<Private>(ostreeRepoFile, true);
        }
    }
}

KMOstreeRepoFile::KMOstreeRepoFile(GFile *file, bool needFree)
{
    OstreeRepoFile *ostreeRepoFile = OSTREE_REPO_FILE(file);
    if (ostreeRepoFile)
    {
        // 不需要释放时，说明传入的对象指针已经有释放的地方，为了此处安全使用，需增加引用计数，以防其他地方将其删除
        if (!needFree)
        {
            g_object_ref(ostreeRepoFile);
        }
        d = std::make_shared<Private>(ostreeRepoFile, true);
    }
}

KMOstreeRepoFile::KMOstreeRepoFile(OstreeRepoFile *file, bool needFree)
{
    if (file)
    {
        // 不需要释放时，说明传入的对象指针已经有释放的地方，为了此处安全使用，需增加引用计数，以防其他地方将其删除
        if (!needFree)
        {
            g_object_ref(file);
        }
        d = std::make_shared<Private>(file, true);
    }
}

KMOstreeRepoFile::~KMOstreeRepoFile() { }

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

    return *this;
}

KMOstreeRepoFile &KMOstreeRepoFile::operator=(KMOstreeRepoFile &&other)
{
    d = other.d;

    return *this;
}

// // 注意：默认不增加引用计数，需要释放
// KMOstreeRepoFile& KMOstreeRepoFile::operator=(OstreeRepoFile* file)
// {
//     if (file)
//     {
//         if (d)
//         {
//             if (d->m_file == file)
//             {
//                 // do nothing
//             }
//             else if (d->m_file)
//             {
//                 if (d->m_needFree)
//                     g_object_unref(d->m_file);
//                 d->m_file = file;
//                 d->m_needFree = true;
//             }
//         }
//         else
//         {
//             d = std::make_shared<Private>(file);
//         }
//     }
//     else
//     {
//         d.reset();
//     }

//     return *this;
// }

// // 注意：默认不增加引用计数，需要释放
// KMOstreeRepoFile& KMOstreeRepoFile::operator=(GFile* file)
// {
//     OstreeRepoFile* ostreeRepoFile = OSTREE_REPO_FILE(file);

//     if (ostreeRepoFile)
//     {
//         if (d)
//         {
//             if (d->m_file == ostreeRepoFile)
//             {
//                 // do nothing
//             }
//             else if (d->m_file)
//             {
//                 if (d->m_needFree)
//                     g_object_unref(d->m_file);
//                 d->m_file = ostreeRepoFile;
//                 d->m_needFree = true;
//             }
//         }
//         else
//         {
//             d = std::make_shared<Private>(ostreeRepoFile);
//         }
//     }
//     else
//     {
//         d.reset();
//     }

//     return *this;
// }

// void KMOstreeRepoFile::setNeedFree(bool needFree)
// {
//     if (d)
//         d->m_needFree = needFree;
// }

OstreeRepoFile *KMOstreeRepoFile::get()
{
    if (d)
    {
        return d->m_file;
    }
    else
    {
        return nullptr;
    }
}

const char *KMOstreeRepoFile::getChecksum()
{
    if (d)
    {
        return ostree_repo_file_get_checksum(d->m_file);
    }
    else
    {
        return nullptr;
    }
}
