// SPDX-License-Identifier: LGPL-3.0-or-later
#include "compat.h"

#include "driveinfo.h"

#include <QDir>

auto DriveInfo::getAll(bool refresh) -> QVector<DriveInfo>
{
    if(!refresh && !all.empty())
        return all;

    all.clear();

    QDir partuuid("/dev/disk/by-partuuid");
    if(!partuuid.exists())
        return all;

    partuuid.setFilter(QDir::Files);
    const auto partitions = partuuid.entryInfoList();
    for(const auto &part: partitions)
    {
        if(!part.isSymLink())
            continue;

        const auto target = QFileInfo{part.symLinkTarget()};

        DriveInfo driveinfo{};
        driveinfo.name = target.fileName();
        if(part.fileName().size() > 11)
        {
            driveinfo.signature_type = DriveInfo::SIGNATURE::GUID;
            driveinfo.signature = QUuid::fromString(part.fileName());
        }

        else
        {
            driveinfo.signature_type = DriveInfo::SIGNATURE::MBR;
            auto parts = part.fileName().split("-");
            uint l = parts[0].toUInt(nullptr, HEX_BASE);
            ushort w1 = parts[1].toUShort(nullptr, HEX_BASE);
            driveinfo.signature = QUuid{l, w1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        }

        const auto &sys_path = QString("/sys/class/block/%1").arg(driveinfo.name);
        if(QFile file{sys_path + "/partition"}; file.open(QIODevice::ReadOnly))
        {
            driveinfo.partition = file.readAll().toUInt();
        }

        if(QFile file{sys_path + "/start"}; file.open(QIODevice::ReadOnly))
        {
            driveinfo.start = file.readAll().toULongLong();
        }

        if(QFile file{sys_path + "/size"}; file.open(QIODevice::ReadOnly))
        {
            driveinfo.size = file.readAll().toULongLong();
        }

        all.append(driveinfo);
    }

    std::sort(std::begin(all), std::end(all));
    return all;
}
