/*
 * Copyright (C) 2026 UBports Foundation.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "NextcloudVendor.h"

#include "../rclone_ops.h"

#include <QString>
#include <QUrl>

using namespace std;
using namespace lomiri::storage::provider;

NextcloudVendor::NextcloudVendor(Context const& ctx)
    : credentials_(make_shared<PasswordCredentials>(
          boost::get<PasswordCredentials>(ctx.credentials)))
{
}

bool NextcloudVendor::is_valid_context(Context const& ctx)
{
    auto const* credentials = boost::get<PasswordCredentials>(&ctx.credentials);
    return credentials
        && !credentials->username.empty() && !credentials->password.empty()
        && (credentials->host.starts_with("http://")
            || credentials->host.starts_with("https://"));
}

Context NextcloudVendor::test_context(string const& host, string const& user,
                                      string const& password)
{
    Context ctx;
    ctx.credentials = PasswordCredentials{user, password, host};
    return ctx;
}

string NextcloudVendor::files_url(string const& host, string const& user)
{
    QString base = QString::fromStdString(host);
    while (base.endsWith('/')) base.chop(1);

    QString encoded_user = QString::fromUtf8(
        QUrl::toPercentEncoding(QString::fromStdString(user)));

    return QStringLiteral("%1/remote.php/dav/files/%2/")
        .arg(base, encoded_user).toStdString();
}

void NextcloudVendor::get_conn_string(shared_ptr<RcloneClient> const& client,
                                      ConnStringCallback cb)
{
    if (!remote_->empty())
    {
        cb(*remote_ + ":", boost::exception_ptr());
        return;
    }

    string name = next_remote_name("nextcloud");

    create_remote(client, name, "webdav", {
        {"url", files_url(credentials_->host, credentials_->username)},
        {"vendor", "nextcloud"},
        {"user", credentials_->username},
        {"pass", credentials_->password},
    }, [cb, remote = remote_, credentials = credentials_, name]
       (boost::exception_ptr const& error) {
        if (error)
        {
            cb(string(), error);
            return;
        }
        *remote = name;
        *credentials = PasswordCredentials{};
        cb(name + ":", boost::exception_ptr());
    });
}
