#ifndef DIRFILE_H
#define DIRFILE_H

#include <cereal/archives/binary.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/types/vector.hpp>
#include <cstdint>
#include <string>
#include <vector>
#include <wx/wx.h>

enum FileType : uint32_t {
    None = 0,
    File,
    Dir,
    Link
};

struct DirFileInfo {

    static wxString GetFileSize(uint64_t size)
    {
        const uint64_t KB = 1024;
        const uint64_t MB = KB * 1024;
        const uint64_t GB = MB * 1024;

        if (size >= GB) {
            return wxString::Format("%.2f GB", static_cast<double>(size) / GB);
        } else if (size >= MB) {
            return wxString::Format("%.2f MB", static_cast<double>(size) / MB);
        } else if (size >= KB) {
            return wxString::Format("%.2f KB", static_cast<double>(size) / KB);
        } else {
            return wxString::Format("%llu B", size);
        }
    }

    static wxString GetStrTime(uint64_t time)
    {
        wxDateTime dt(static_cast<time_t>(time));
        wxString dateStr = dt.Format("%Y/%m/%d %H:%M:%S");
        return dateStr;
    }

    static wxString GetFileTypeName(FileType type)
    {
        switch (type) {
        case None:
            return _("None");
        case File:
            return _("File");
        case Dir:
            return _("Dir");
        case Link:
            return _("Link");
        default:
            return _("Unknown");
        }
    }

    std::string name;
    uint64_t size = 0;
    FileType type = None;
    std::string fullPath;
    uint16_t permission = 0;
    uint64_t lastModifyTime = 0;

    DirFileInfo() = default;

    template <class Archive> void serialize(Archive& archive)
    {
        archive(CEREAL_NVP(name), CEREAL_NVP(size), CEREAL_NVP(type), CEREAL_NVP(fullPath), CEREAL_NVP(permission),
                CEREAL_NVP(lastModifyTime));
    }
};

struct DirFileInfoVec {
    std::vector<DirFileInfo> vec;
    template <class Archive> void serialize(Archive& archive)
    {
        archive(CEREAL_NVP(vec));
    }
};

#endif