/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2019 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 2 of the License, 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#include "hostnamedialog.h"
#include <QVBoxLayout>
#include <QFrame>
#include <QLabel>
#include <QProcess>
#include <QRegExp>
#include <QDebug>
#include <QRegExpValidator>
#include <regex>
#include <string>
using namespace std;

HostNameDialog::HostNameDialog(QWidget *parent):
    KDialog(parent)
{
    this->setWindowFlags(Qt::Dialog);
    setWindowIcon("ukui-control-center");
    setWindowTitle(tr("Set HostName"));
    InitUi();
    setEdit();
    setupComponent();
    initConnect();
}

HostNameDialog::~HostNameDialog()
{

}

void HostNameDialog::InitUi()
{
    setFixedSize(480 ,198);
    QVBoxLayout *mInputPwdLyt = new QVBoxLayout(this);
    mInputPwdLyt->setContentsMargins(24, 24, 24, 24);
    mInputPwdLyt->setSpacing(0);

    QFrame *mInputPwdFrame = new QFrame(this);
    mInputPwdFrame->setFixedSize(432, 36);
    mInputPwdFrame->setFrameShape(QFrame::NoFrame);

    QHBoxLayout *mLyt_1= new QHBoxLayout(mInputPwdFrame);
    mLyt_1->setContentsMargins(0, 0, 0, 0);
    mLyt_1->setSpacing(8);

    QLabel *mHostNameLabel = new QLabel(mInputPwdFrame);
    mHostNameLabel->setFixedSize(102, 36);
    QFontMetrics fontMetrics(mHostNameLabel->font());
    QString hostnameText = tr("HostName");
    int fontSize = fontMetrics.width(hostnameText);
    if (fontSize > mHostNameLabel->width()) {
        QString hostnameNew = fontMetrics.elidedText(hostnameText, Qt::ElideRight, mHostNameLabel->width());
        mHostNameLabel->setText(hostnameNew);
        mHostNameLabel->setToolTip(hostnameText);
    } else {
        mHostNameLabel->setText(hostnameText);
        mHostNameLabel->setToolTip("");
    }

    mHostNameEdit = new QLineEdit(mInputPwdFrame);
    mHostNameEdit->setFixedSize(322, 36);
    mHostNameEdit->installEventFilter(this);

    mLyt_1->addWidget(mHostNameLabel);
    mLyt_1->addWidget(mHostNameEdit);

    mTipLabel = new QLabel(this);
    mTipLabel->setFixedSize(432, 24);
    mTipLabel->setContentsMargins(114, 0, 0, 0);
    mTipLabel->setStyleSheet("QLabel{color : red; font-size : 14px}");
    mTipLabel->setVisible(false);

    QFrame *mInputPwdFrame_1 = new QFrame(this);
    mInputPwdFrame_1->setFixedWidth(432);
    mInputPwdFrame_1->setFrameShape(QFrame::NoFrame);

    QHBoxLayout *mLyt_2= new QHBoxLayout(mInputPwdFrame_1);
    mLyt_2->setContentsMargins(0, 0, 0, 0);
    mLyt_2->setSpacing(16);

    mConfirmBtn = new QPushButton(mInputPwdFrame_1);
    mConfirmBtn->setMinimumWidth(96);
    mConfirmBtn->setText(tr("Confirm"));
    mConfirmBtn->setProperty("isImportant", true);

    mCancelBtn = new QPushButton(mInputPwdFrame_1);
    mCancelBtn->setMinimumWidth(96);
    mCancelBtn->setText(tr("Cancel"));
    mCancelBtn->setProperty("useButtonPalette", true);

    mLyt_2->addStretch();
    mLyt_2->addWidget(mCancelBtn);
    mLyt_2->addWidget(mConfirmBtn);

    mInputPwdLyt->addWidget(mInputPwdFrame);
    mInputPwdLyt->addWidget(mTipLabel);
    mInputPwdLyt->addStretch();
    mInputPwdLyt->addWidget(mInputPwdFrame_1);

    this->mainWidget()->setLayout(mInputPwdLyt);
}

void HostNameDialog::hostNameEditSlot(QString pwd) {
    if (pwd.isEmpty()) {
        mTipLabel->setText(tr("Must be 1-64 characters long"));
        mTipLabel->setVisible(true);
    } else if (pwd.length() > 64) {
        mTipLabel->setText("");
        mHostNameEdit->setText(pwd.mid(0, 64));
        mTipLabel->setVisible(true);
    } else {
        mTipLabel->setVisible(!isMatch(pwd));
    }

    if (!mTipLabel->text().isEmpty() || mHostNameEdit->text().isEmpty()) {
        mConfirmBtn->setEnabled(false);
    } else {
        mConfirmBtn->setEnabled(true);
    }
}

void HostNameDialog::initConnect()
{
    connect(mHostNameEdit, &QLineEdit::textEdited, this, [=](QString pwd) {
        hostNameEditSlot(pwd);
    });

    connect(mCancelBtn, &QPushButton::clicked, this, [=]() {
        this->close();
    });

    connect(mConfirmBtn, &QPushButton::clicked, this, [=]() {
        if (mfirsthostname != mHostNameEdit->text()) {
            setHostname(mHostNameEdit->text());
        }
        this->close();
    });
}

void HostNameDialog::setEdit()
{
    QRegExp rx("[a-zA-Z0-9.-]*");
    QRegExpValidator *validator = new QRegExpValidator(rx , this);
    mHostNameEdit->setValidator(validator);
}

void HostNameDialog::setupComponent()
{
    mfirsthostname = UkccCommon::getHostName();
    mHostNameEdit->setText(mfirsthostname);
}

void HostNameDialog::setHostname(QString hostname)
{
    //修改/etc/hosts文件中的主机名
    QDBusInterface *sethostnameDbus = new QDBusInterface("com.control.center.qt.systemdbus",
                                                             "/",
                                                             "com.control.center.interface",
                                                             QDBusConnection::systemBus());

    QDBusReply<bool> reply = sethostnameDbus->call("sethostname", hostname);
    qDebug() << Q_FUNC_INFO << reply.isValid() << hostname;
    if (reply.isValid() && reply.value()) {
        QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
        env.insert("LANG","en_US");
        QProcess *process = new QProcess;
        process->setProcessEnvironment(env);
        process->start(QString("%1%2").arg("hostnamectl set-hostname ").arg(hostname));
        process->waitForFinished();
        delete process;
    }
    delete sethostnameDbus;
    sethostnameDbus = nullptr;
}

bool HostNameDialog::isMatch(QString hostname)
{
    bool ismatch = true;
    string str = hostname.toStdString();
    string::const_iterator iter_begin = str.cbegin();
    string::const_iterator iter_end = str.cend();

    if (regex_search(iter_begin, iter_end, regex("^[-.]")) || regex_search(iter_begin, iter_end, regex("[-.]$"))) {
        mTipLabel->setText(tr("Hostname must start or end with a number and a letter"));
        ismatch = false;
    }
    if (regex_search(iter_begin, iter_end, regex("[-][.]")) || regex_search(iter_begin, iter_end, regex("[.][-]"))) {
        int position = mHostNameEdit->cursorPosition();
        if (regex_search(iter_begin, iter_end, regex("[-][.]"))) {
           mHostNameEdit->setText(regex_replace(str, regex("[-][.]"), "-").c_str());
        } else {
            mHostNameEdit->setText(regex_replace(str, regex("[.][-]"), ".").c_str());
        }
        mHostNameEdit->setCursorPosition(position - 1);
        mTipLabel->setText(tr("Hostname cannot have consecutive ' - ' and ' . '"));
        ismatch = false;
    }
    if (regex_search(iter_begin, iter_end, regex("[.][.]"))) {
        int position = mHostNameEdit->cursorPosition();
        mHostNameEdit->setText(regex_replace(str, regex("[.][.]"), ".").c_str());
        mHostNameEdit->setCursorPosition(position - 1);
        mTipLabel->setText(tr("Hostname cannot have consecutive ' . '"));
        ismatch = false;
    }
    if (ismatch) {
        mTipLabel->setText("");
    }
    return ismatch;
}
