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

#include "KMFileInfo.h"

class KMFileInfo::Private
{
public:
    Private();
    Private(GFileInfo *fileInfo);
    ~Private();

    GFileInfo *m_fileInfo = nullptr;
    bool m_isValid = false;
};

KMFileInfo::Private::Private()
{
    m_fileInfo = g_file_info_new();
    m_isValid = true;
}

KMFileInfo::Private::Private(GFileInfo *fileInfo)
{
    if (fileInfo)
    {
        m_fileInfo = fileInfo;
        m_isValid = true;
    }
    else
    {
        m_isValid = false;
    }
}

KMFileInfo::Private::~Private()
{
    if (m_fileInfo)
        g_object_unref(m_fileInfo);
}

KMFileInfo::KMFileInfo(bool empty /* = false*/)
{
    if (!empty)
        d = std::make_shared<Private>();
}

KMFileInfo::KMFileInfo(const std::string &filename)
    : d(std::make_shared<Private>())
{
    setName(filename);
}

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

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

KMFileInfo::KMFileInfo(GFileInfo *fileinfo)
    : d(std::make_shared<Private>(fileinfo))
{
}

KMFileInfo::~KMFileInfo() { }

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

    return *this;
}

// 不进行深拷贝
KMFileInfo &KMFileInfo::operator=(GFileInfo *fileinfo)
{
    if (fileinfo)
    {
        if (d)
        {
            if (d->m_fileInfo == fileinfo)
            {
                // do nothing
            }
            else if (d->m_fileInfo)
            {
                g_object_unref(d->m_fileInfo);
                d->m_fileInfo = fileinfo;
            }
        }
        else
        {
            d = std::make_shared<Private>(fileinfo);
        }
    }
    else
    {
        d.reset();
    }

    return *this;
}

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

    return *this;
}

void KMFileInfo::setName(const std::string &filename)
{
    if (!d)
        d = std::make_shared<Private>();

    g_file_info_set_name(d->m_fileInfo, filename.c_str());
}

std::string KMFileInfo::getName() const
{
    if (d)
        return g_file_info_get_name(d->m_fileInfo);
    else
        return "";
}

void KMFileInfo::setFileType(GFileType type)
{
    if (!d)
        d = std::make_shared<Private>();

    g_file_info_set_file_type(d->m_fileInfo, type);
}

GFileType KMFileInfo::getFileType() const
{
    return g_file_info_get_file_type(d->m_fileInfo);
}

void KMFileInfo::setAttribute(const std::string &attribute, std::uint32_t attrValue)
{
    if (!d)
        d = std::make_shared<Private>();

    g_file_info_set_attribute_uint32(d->m_fileInfo, attribute.c_str(), attrValue);
}

void KMFileInfo::setValid(bool valid)
{
    d->m_isValid = valid;
}

KMFileInfo::operator bool() const
{
    return d.operator bool() && d->m_isValid;
}

GFileInfo *KMFileInfo::get()
{
    if (d)
        return d->m_fileInfo;
    else
        return nullptr;
}

std::uint64_t KMFileInfo::getSize() const
{
    return g_file_info_get_size(d->m_fileInfo);
}
