/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * 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 "sharemain.h"

#include <QProcess>
#include <QHBoxLayout>
#include <QAbstractButton>
#include <QPushButton>
#include <QMessageBox>
#include <QInputDialog>
#include <QTimer>
#include <QDBusInterface>
#include <QDBusConnection>

#include "common.h"

ShareMain::ShareMain(QWidget *parent) :
    QWidget(parent)
{
    mVlayout = new QVBoxLayout(this);
    mVlayout->setContentsMargins(0, 0, 0, 0);
    initUI();
    initConnection();
}

ShareMain::~ShareMain()
{
}

void ShareMain::initUI()
{
    SettingGroup *mVinoFrame = new SettingGroup;
    mVinoTitleLabel = new TitleLabel(this);
    mVinoTitleLabel->setText(tr("Remote Desktop"));

    mEnableWidget = new SwitchWidget(tr("Allow others to view your desktop"));
    //~ contents_path /Vino/Allow connection to control screen
    mViewWidget = new SwitchWidget(tr("Allow connection to control screen"));
    //~ contents_path /Vino/You must confirm every visit for this machine
    mSecurityWidget = new SwitchWidget(tr("You must confirm every visit for this machine"));
    //~ contents_path /Vino/Require user to enter this password:
    mSecurityPwdWidget = new SwitchWidget(tr("Require user to enter this password: "));
    mPwdinputBtn = new QPushButton(this);
    mSecurityPwdWidget->insertWidget(1, mPwdinputBtn);


    mVinoFrame->addWidget(mEnableWidget);
    mVinoFrame->addWidget(mViewWidget);
    mVinoFrame->addWidget(mSecurityWidget);
    mVinoFrame->addWidget(mSecurityPwdWidget);

    mVlayout->addWidget(mVinoTitleLabel);
    mVlayout->addWidget(mVinoFrame);
    mVlayout->addStretch();
}

void ShareMain::initConnection()
{
    QByteArray id(kVinoSchemas);
    if (QGSettings::isSchemaInstalled(id)) {
        mVinoGsetting = new QGSettings(kVinoSchemas, QByteArray(), this);

        initEnableStatus();

        connect(mEnableWidget, &SwitchWidget::stateChanged, this, [=](bool status) {
            Common::buriedSettings(QStringLiteral("Vino"), "whether allow others to connect to your desktop remotely", QString("settings"), status ? "true" : "false");
            enableSlot(status);
        });
        connect(mViewWidget, &SwitchWidget::stateChanged, this, [=](bool status) {
            Common::buriedSettings(QStringLiteral("Vino"), "whether allow others to control your desktop remotely", QString("settings"), status ? "true" : "false");
            viewBoxSlot(status);
        });
        connect(mSecurityWidget, &SwitchWidget::stateChanged, this, [=](bool status) {
            Common::buriedSettings(QStringLiteral("Vino"), "whether to confirm each visit for the local mach", QString("settings"), status ? "true" : "false");
            accessSlot(status);
        });
        connect(mSecurityPwdWidget, &SwitchWidget::stateChanged, this, [=](bool status) {
            Common::buriedSettings(QStringLiteral("Vino"), "whether password verification is required", QString("settings"), status ? "true" : "false");
            pwdEnableSlot(status);
        });
        connect(mPwdinputBtn, &QPushButton::clicked, this, [=]() {
            Common::buriedSettings(QStringLiteral("Vino"), "set password", QString("clicked"));
            pwdInputSlot();
        });

    }
}

void ShareMain::initEnableStatus()
{
    bool isShared = mVinoGsetting->get(kVinoViewOnlyKey).toBool();
    bool secPwd = mVinoGsetting->get(kVinoPromptKey).toBool();
    QString pwd = mVinoGsetting->get(kAuthenticationKey).toString();
    secpwd = mVinoGsetting->get(kVncPwdKey).toString();

    mSecurityWidget->setChecked(secPwd);
    mViewWidget->setChecked(!isShared);
    if (pwd == "vnc") {
        if (secpwd == "keyring") {
            mSecurityPwdWidget->setChecked(false);
            mPwdinputBtn->hide();
            mVinoGsetting->set(kAuthenticationKey, "none");
        } else {
            mSecurityPwdWidget->setChecked(true);
            mPwdinputBtn->setText(QByteArray::fromBase64(secpwd.toLatin1()));
        }
    } else {
        mSecurityPwdWidget->setChecked(false);
        mPwdinputBtn->setVisible(false);
    }

    QProcess *process = new QProcess;

    process->start("systemctl", QStringList() << "--user" << "is-active" << "vino-server.service");
    process->waitForFinished();

    setFrameVisible((process->readAllStandardOutput().replace("\n", "") == "active"));
    delete process;
}

void ShareMain::setFrameVisible(bool visible)
{
    mEnableWidget->setChecked(visible);
    mViewWidget->setVisible(visible);
    mSecurityWidget->setVisible(visible);
    mSecurityPwdWidget->setVisible(visible);
}

void ShareMain::setVinoService(bool status)
{
    QDBusInterface vinoIfc("org.ukui.SettingsDaemon",
                           "/org/ukui/SettingsDaemon/Sharing",
                           "org.ukui.SettingsDaemon.Sharing",
                           QDBusConnection::sessionBus());
    if (vinoIfc.isValid()) {
        if (status) {
            vinoIfc.call("EnableService", "vino-server");
        } else {
            vinoIfc.call("DisableService", "vino-server");
        }
    }
}

void ShareMain::enableSlot(bool status)
{
    setFrameVisible(status);
    setVinoService(status);
}

void ShareMain::viewBoxSlot(bool status)
{
    mVinoGsetting->set(kVinoViewOnlyKey, !status);
}

void ShareMain::accessSlot(bool status)
{
    if (status) {
        mVinoGsetting->set(kVinoPromptKey, true);
    } else {
        mVinoGsetting->set(kVinoPromptKey, false);
    }
}

void ShareMain::pwdEnableSlot(bool status)
{
    if (status) {
        mPwdinputBtn->setVisible(secpwd == "keyring" ? false:true);
        mPwdinputBtn->setText(QByteArray::fromBase64(mVinoGsetting->get(kVncPwdKey).toString().toLatin1()));
        pwdInputSlot();
        mPwdinputBtn->setVisible(status);
        if (mVinoGsetting->get(kAuthenticationKey).toString() == "none") {
            mSecurityPwdWidget->setChecked(false);
        }

    } else {
        mPwdinputBtn->setVisible(false);
        mVinoGsetting->set(kAuthenticationKey, "none");
    }
}

void ShareMain::pwdInputSlot()
{
    InputPwdDialog *mwindow = new InputPwdDialog(mVinoGsetting,this);
    mwindow->exec();
    secpwd = mVinoGsetting->get(kVncPwdKey).toString();
    mPwdinputBtn->setText(QByteArray::fromBase64(secpwd.toLatin1()));
}
