/*
 * advoptsdialog.cc - Implementation of the UI.AdvOpts page
 * horizon-qt5, the Qt 5 user interface for
 * Project Horizon
 *
 * Copyright (c) 2023 Adélie Linux and contributors.  All rights reserved.
 * This code is licensed under the AGPL 3.0 license, as noted in the
 * LICENSE-code file in the root directory of this repository.
 *
 * SPDX-License-Identifier: AGPL-3.0-only
 */

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QLabel>
#include <QLineEdit>
#include <QTextEdit>
#include <QPushButton>

#include "advoptsdialog.hh"

void updateSubarchBox(QComboBox *subarchBox, HorizonWizard::Arch arch, HorizonWizard *wizard) {
    subarchBox->clear();
    auto current = wizard->subarch;
    for(const auto &subarch : wizard->subarchesForArch(arch)) {
        const auto text = QString::fromStdString(subarch.first);
        subarchBox->addItem(text, QVariant::fromValue<int>(subarch.second));
        if(current == subarch.second) {
            subarchBox->setCurrentText(text);
        }
    }
}

inline void configTextEdit(QTextEdit *edit) {
    edit->setAcceptRichText(false);
    edit->setFixedHeight(70);
    edit->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    edit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

AdvOptsDialog::AdvOptsDialog(HorizonWizard *wizard, QWidget *parent) : QDialog(parent) {
    setWindowTitle(tr("System Installation Advanced Options"));

    auto warnLabel = new QLabel(tr("<b>WARNING</b>: Modifying <u>any</u> of the settings on this page may cause installation to fail."));
    warnLabel->setTextFormat(Qt::RichText);

    auto version = new QLabel(tr("&Version to install:"));
    auto versionEdit = new QLineEdit(this);
    versionEdit->setText(QString::fromStdString(wizard->version));
    version->setBuddy(versionEdit);

    auto repos = new QLabel(tr("URLs for package &repositories:"));
    auto repoEdit = new QTextEdit(this);
    configTextEdit(repoEdit);
    repoEdit->setPlainText(wizard->repositories.join("\n"));
    repos->setBuddy(repoEdit);

    auto keys = new QLabel(tr("URLs for package &signing keys:  (<i>must begin with https:</i>)"));
    keys->setTextFormat(Qt::RichText);
    auto keyEdit = new QTextEdit(this);
    configTextEdit(keyEdit);
    keyEdit->setPlainText(wizard->signing_keys.join("\n"));
    keys->setBuddy(keyEdit);

    auto arch = new QLabel(tr("Target CPU &architecture:"));
    auto archBox = new QComboBox(this);
    archBox->setEditable(false);
    for(const auto &arches : wizard->arches) {
        const auto text = QString::fromStdString(arches.first);
        archBox->addItem(text, QVariant::fromValue<int>(arches.second));
        if(wizard->arch == arches.second) {
            archBox->setCurrentText(text);
        }
    }
    arch->setBuddy(archBox);

    auto subarch = new QLabel(tr("Sub-architecture (if applicable):"));
    auto subarchBox = new QComboBox(this);
    subarchBox->setEditable(false);
    updateSubarchBox(subarchBox, wizard->arch, wizard);
    subarch->setBuddy(subarchBox);

    connect(archBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index) {
        updateSubarchBox(subarchBox, static_cast<HorizonWizard::Arch>(archBox->itemData(index).toInt()), wizard);
    });

    auto saveButton = new QPushButton(tr("&Save"));
    connect(saveButton, &QPushButton::clicked,
            [this, wizard, archBox, subarchBox, versionEdit, repoEdit, keyEdit](bool) {
        wizard->arch = static_cast<HorizonWizard::Arch>(archBox->currentData().toInt());
        wizard->subarch = static_cast<HorizonWizard::Subarch>(subarchBox->currentData().toInt());
        wizard->version = versionEdit->text().toStdString();
        wizard->repositories = repoEdit->toPlainText().split('\n');
        wizard->signing_keys = keyEdit->toPlainText().split('\n');
        this->accept();
    });
    auto cancelButton = new QPushButton(tr("&Cancel"));
    connect(cancelButton, &QPushButton::clicked, [this](bool) {
        this->reject();
    });

    auto buttonLayout = new QHBoxLayout;
    buttonLayout->addWidget(cancelButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(saveButton);

    auto layout = new QVBoxLayout;
    layout->addWidget(warnLabel);
    layout->addSpacing(25);
    layout->addWidget(arch);
    layout->addWidget(archBox);
    layout->addWidget(subarch);
    layout->addWidget(subarchBox);
    layout->addSpacing(25);
    layout->addWidget(version);
    layout->addWidget(versionEdit);
    layout->addSpacing(25);
    layout->addWidget(repos);
    layout->addWidget(repoEdit);
    layout->addSpacing(25);
    layout->addWidget(keys);
    layout->addWidget(keyEdit);
    layout->addSpacing(25);
    layout->addLayout(buttonLayout);
    this->setLayout(layout);
}