/*
    SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "backendmodel.h"

#include <KPublicTransport/Backend>
#include <KPublicTransport/Manager>

#include <QDebug>

using namespace KPublicTransport;

namespace KPublicTransport {
class BackendModelPrivate
{
public:
    Manager *mgr = nullptr;
};
}

BackendModel::BackendModel(QObject *parent)
    : QAbstractListModel(parent)
    , d(new BackendModelPrivate)
{
}

BackendModel::~BackendModel() = default;

Manager* BackendModel::manager() const
{
    return d->mgr;
}

void BackendModel::setManager(Manager *mgr)
{
    if (d->mgr == mgr) {
        return;
    }

    beginResetModel();
    d->mgr = mgr;
    connect(mgr, &Manager::configurationChanged, this, [this]() {
        emit dataChanged(index(0, 0), index(rowCount() - 1, 0));
    });
    endResetModel();
    emit managerChanged();
}

int BackendModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid() || !d->mgr) {
        return 0;
    }
    return d->mgr->backends().size();
}

QVariant BackendModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || !d->mgr) {
        return {};
    }

    const auto &backend = d->mgr->backends()[index.row()];
    switch (role) {
        case NameRole:
            return backend.name();
        case DescriptionRole:
            return backend.description();
        case IdentifierRole:
            return backend.identifier();
        case SecureRole:
            return backend.isSecure();
        case ItemEnabledRole:
            return backend.isSecure() || d->mgr->allowInsecureBackends();
        case BackendEnabledRole:
            if (!backend.isSecure() && !d->mgr->allowInsecureBackends()) {
                return false;
            }
            return d->mgr->isBackendEnabled(backend.identifier());
        case Qt::CheckStateRole:
            if (!backend.isSecure() && !d->mgr->allowInsecureBackends()) {
                return Qt::Unchecked;
            }
            return d->mgr->isBackendEnabled(backend.identifier()) ? Qt::Checked : Qt::Unchecked;
        case PrimaryCountryCodeRole:
            return backend.primaryCountryCode();
    }

    return {};
}

bool BackendModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    const auto &backend = d->mgr->backends()[index.row()];
    switch (role) {
        case BackendModel::BackendEnabledRole:
            d->mgr->setBackendEnabled(backend.identifier(), value.toBool());
            return true;
        case Qt::CheckStateRole:
            d->mgr->setBackendEnabled(backend.identifier(), value.toInt() == Qt::Checked);
            return true;
    }
    return false;
}

Qt::ItemFlags BackendModel::flags(const QModelIndex &index) const
{
    auto f = QAbstractListModel::flags(index);
    if (!d->mgr || !index.isValid()) {
        return f;
    }
    f |= Qt::ItemIsUserCheckable;

    const auto &backend = d->mgr->backends()[index.row()];
    if (!d->mgr->allowInsecureBackends() && !backend.isSecure()) {
        return f & ~Qt::ItemIsEnabled;
    }

    return f;
}

QHash<int, QByteArray> BackendModel::roleNames() const
{
    auto names = QAbstractListModel::roleNames();
    names.insert(NameRole, "name");
    names.insert(DescriptionRole, "description");
    names.insert(IdentifierRole, "identifier");
    names.insert(SecureRole, "isSecure");
    names.insert(ItemEnabledRole, "itemEnabled");
    names.insert(BackendEnabledRole, "backendEnabled");
    names.insert(PrimaryCountryCodeRole, "primaryCountryCode");
    return names;
}
