Files

148 lines
3.8 KiB
C++
Raw Permalink Normal View History

2026-07-09 09:17:30 +00:00
#include "LocalStateHelper.h"
#include <QFile>
#include <QFileInfo>
#include <QJsonDocument>
#include <QDir>
LocalStateHelper::LocalStateHelper(const QString& baseDir)
: m_baseDir(baseDir)
, m_filePath(baseDir + "/config/local_state.json")
{
}
bool LocalStateHelper::loadState(const QString& relativePath)
{
m_filePath = m_baseDir + "/" + relativePath;
QFile file(m_filePath);
if (!file.exists())
{
QDir dir(QFileInfo(m_filePath).path());
if (!dir.exists() && !dir.mkpath("."))
{
m_error = QString("Cannot create state directory: %1").arg(dir.path());
return false;
}
m_state = QJsonObject{
{"max_policy_seq", 0},
{"last_success_run_at", QString()},
{"last_online_verified_at", QString()},
{"last_success_version", QString()}
};
m_loaded = true;
if (!saveState())
{
m_error = QString("Cannot write new state file: %1").arg(m_filePath);
return false;
}
return true;
}
if (!file.open(QIODevice::ReadOnly))
{
m_error = QString("Cannot open state file: %1").arg(m_filePath);
return false;
}
QByteArray raw = file.readAll();
file.close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(raw, &parseError);
if (parseError.error != QJsonParseError::NoError || !doc.isObject())
{
m_error = QString("Invalid state JSON: %1").arg(parseError.errorString());
return false;
}
m_state = doc.object();
m_loaded = true;
return true;
}
bool LocalStateHelper::saveState() const
{
if (!m_loaded)
return false;
QFile file(m_filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
return false;
}
QJsonDocument doc(m_state);
file.write(doc.toJson(QJsonDocument::Indented));
file.close();
return true;
}
bool LocalStateHelper::isLoaded() const
{
return m_loaded;
}
QString LocalStateHelper::errorString() const
{
return m_error;
}
qint64 LocalStateHelper::maxPolicySeq() const
{
return m_state.value("max_policy_seq").toVariant().toLongLong();
}
QDateTime LocalStateHelper::lastSuccessRunAt() const
{
return QDateTime::fromString(m_state.value("last_success_run_at").toString(), Qt::ISODate);
}
QDateTime LocalStateHelper::lastOnlineVerifiedAt() const
{
return QDateTime::fromString(m_state.value("last_online_verified_at").toString(), Qt::ISODate);
}
QString LocalStateHelper::lastSuccessVersion() const
{
return m_state.value("last_success_version").toString();
}
bool LocalStateHelper::isPolicySeqRolledBack(qint64 policySeq) const
{
if (!m_loaded)
return false;
return policySeq < maxPolicySeq();
}
bool LocalStateHelper::isSystemTimeRewound() const
{
if (!m_loaded)
return false;
const QDateTime now = QDateTime::currentDateTimeUtc();
const QDateTime lastRun = lastSuccessRunAt();
const QDateTime lastOnline = lastOnlineVerifiedAt();
return (lastRun.isValid() && now < lastRun)
|| (lastOnline.isValid() && now < lastOnline);
}
void LocalStateHelper::updateAfterSuccessfulRun(const QString& currentVersion, qint64 policySeq)
{
if (!m_loaded)
m_loaded = true;
m_state["last_success_run_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
m_state["last_success_version"] = currentVersion;
if (policySeq > maxPolicySeq())
m_state["max_policy_seq"] = policySeq;
}
void LocalStateHelper::updateOnlineVerified(qint64 policySeq)
{
if (!m_loaded)
m_loaded = true;
m_state["last_online_verified_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
if (policySeq > maxPolicySeq())
m_state["max_policy_seq"] = policySeq;
}