/** Copyright (c) 2020-2023 The Creators of Simphone

    class KeyGen (LoginDialog): display key generation progress

    See the file COPYING.LESSER.txt for copying permission.
**/

#include "keygen.h"
#include "ui_keygen.h"

#include "qtfix.h"
#include "contacts.h"

#ifndef _WIN32
#include <unistd.h>
#endif

KeyGen::KeyGen(QWidget * parent)
  : Parent(parent), ui(new Ui::KeyGen), m_time2gen(0), m_val(0), m_autoShow(false), m_finished(false), m_timer(this)
{
  ui->setupUi(this);
  QEvent event(QEvent::PaletteChange);
  changeEvent(&event);

  ui->addrValueLabel_2->setText(qtfix::fixColorString(ui->addrValueLabel_2->text(), SimParam::getColorString(true)));
  ui->okButton->setText(qApp->translate("QDialogButtonBox", "OK"));

  qtfix::fixPointSize(ui->textLabel, font().pointSize());
  qtfix::fixPointSize(ui->addrValueLabel, font().pointSize());
  qtfix::fixPointSize(ui->okButton, font().pointSize());

  connect(SimCore::get(), SIGNAL(signalKeygen(const QString &, simnumber)),
          this, SLOT(onSignalKeygen(const QString &, simnumber)));
  connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout()));
  connect(this, SIGNAL(finished(int)), this, SLOT(onFinished(int)));
  setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);

  qtfix::fixStyleSheet(ui->lineEdit);
  ui->lineEdit->installEventFilter(this);

  ui->label->setPixmap(QPixmap(":/welcome") /*.scaledToWidth(width() - 80, Qt::SmoothTransformation)*/);
  qtfix::fixMenuBar(ui->menubar, adjustToBiggerSize(), ui->verticalLayout);
}

KeyGen::~KeyGen()
{
  ui->lineEdit->removeEventFilter(this);
  delete ui;
}

void KeyGen::showNickEdit()
{
  m_autoShow = true;
  if (ui->addrValueLabel->text().isEmpty()) {
    ui->addrValueLabel_1->hide();
    ui->addrValueLabel->hide();
    ui->addrValueLabel_2->hide();
  }
  ui->nickLabel->show();
  ui->lineEdit->show();
  ui->lineEdit->setFocus();
}

void KeyGen::closeEvent(QCloseEvent * event)
{
  onFinished(0);
  on_okButton_clicked();
  SimCore::get()->setLoginDialog(0);
  Parent::closeEvent(event);
}

void KeyGen::changeEvent(QEvent * event)
{
  switch (int(event->type())) {
    case QEvent::FontChange:
      if (!m_finished) break;
      return;

    case QEvent::PaletteChange:
      if (qApp->styleSheet().isEmpty()) {
        QPalette p = QApplication::palette();
        p.setColor(QPalette::Inactive, QPalette::Highlight, p.color(QPalette::Active, QPalette::Highlight));
        p.setColor(QPalette::Inactive, QPalette::HighlightedText, p.color(QPalette::Active, QPalette::HighlightedText));
        ui->addrValueLabel->setPalette(p);
        prepareLanguage(ui->menuHelp, ui->actionEnglish, ui->actionFrench, ui->actionGerman);
      }
      break;

    case QEvent::LanguageChange:
      QString qs = ui->addrValueLabel->text();
      ui->retranslateUi(this);
      ui->addrValueLabel->setText(qs);
      ui->label->setPixmap(QPixmap(":/welcome"));
      ui->okButton->setText(qApp->translate("QDialogButtonBox", "OK"));
      ui->textLabel->setText(tr("Calculating your RSA key for the first time. Please, wait..."));
      onTimerTimeout();
  }
  Parent::changeEvent(event);
}

void KeyGen::on_okButton_clicked()
{
  if (ui->nickLabel->isVisible()) {
    QString nick = ui->lineEdit->text().trimmed();

    int simres = sim_contact_set_(0, CONTACT_KEY_NICK, sim_pointer_new(nick.toUtf8().data()));
    QString simerr = nick.isEmpty() ? tr("Please, enter a nickname") : SimCore::getError(simres);
    SimCore::get()->getUserContacts();
    if (simres != SIM_OK) {
      SimCore::execMessageBox(true, tr("Setting your nickname not successful (%1)").arg(simres), simerr);
      return;
    }
    sim_audio_hangup_(0);
  }

  qtfix::hideMinimizedWindow(this);
  SimCore::get()->setLoginDialog(0);
  m_finished = true;

  if (m_autoShow) SimCore::showContacts();
  m_autoShow = false;
}

void KeyGen::on_actionEnglish_triggered()
{
  Parent::on_actionEnglish_triggered(ui->actionEnglish, ui->actionFrench, ui->actionGerman);
}

void KeyGen::on_actionFrench_triggered()
{
  Parent::on_actionFrench_triggered(ui->actionEnglish, ui->actionFrench, ui->actionGerman);
}

void KeyGen::on_actionGerman_triggered()
{
  Parent::on_actionGerman_triggered(ui->actionEnglish, ui->actionFrench, ui->actionGerman);
}

void KeyGen::onFinished(int)
{
  /*if (m_time2gen)*/ _exit(0);
}

void KeyGen::onTimerTimeout()
{
  qint64 seconds = m_elapsedTime.elapsed();
  int maxVal = ui->progressBar->maximum();
  int val = m_time2gen > 0 ? maxVal - int(maxVal * (m_time2gen - seconds) / m_time2gen) : m_val + 1;

  ui->progressBar->setValue(m_val = val);
  ui->elapsedLabel->setText(tr("Elapsed: %1").arg(Contact::convertTimeToString(seconds / 1000)));
  ui->estimatedLabel->setText(tr("Estimated: %1").arg(Contact::convertTimeToString(m_time2gen / 1000)));
}

void KeyGen::onSignalKeygen(const QString & address, simnumber time2gen)
{
  bool init = address == "init";
  m_finished = false;
  if (!time2gen) {
    m_timer.stop();
    m_time2gen = 0;
    ui->textLabel->hide();
    ui->progressBar->hide();
    ui->elapsedLabel->hide();
    ui->estimatedLabel->hide();
    if (!address.isEmpty()) {
      ui->addrValueLabel->setText(address.toUtf8().data());
      ui->addrValueLabel_1->show();
      ui->addrValueLabel->show();
      ui->addrValueLabel_2->show();
    } else {
      ui->addrValueLabel_1->hide();
      ui->addrValueLabel->hide();
      ui->addrValueLabel_2->hide();
    }
    qtfix::hideMinimizedWindow(this);
    SimCore::get()->setLoginDialog(0);
    ui->okButton->setEnabled(true);
    setWindowTitle(tr("Public key generated"));
  } else {
    ui->textLabel->setText(tr("Calculating your RSA key for the first time. Please, wait..."));
    if (!m_time2gen || init) {
      if (init) ui->textLabel->setText(tr("Checking the speed of your computer. Please, wait..."));
      m_elapsedTime.start();
      setWindowTitle(tr("Generating public key"));
      ui->okButton->setEnabled(false);
      ui->nickLabel->hide();
      ui->lineEdit->hide();
      ui->addrValueLabel->setText("");
      ui->addrValueLabel->hide();
      ui->addrValueLabel_1->hide();
      ui->addrValueLabel_2->hide();
      ui->textLabel->show();
      ui->progressBar->show();
      ui->elapsedLabel->show();
      ui->estimatedLabel->show();
      ui->estimatedLabel->setText("");
      ui->elapsedLabel->setText("");
      ui->progressBar->setMaximum(100);
      ui->progressBar->setValue(0);
      restorePosition();
      qtfix::showActivateWindow(this, true);
      SimCore::get()->setLoginDialog(this);
      m_timer.start(1000);
      m_time2gen = -1;
      m_val = 0;
    }

    if (!init) {
      if (m_time2gen <= 0) m_time2gen = m_elapsedTime.elapsed(); // add elapsed time to estimated max
      m_time2gen += time2gen * 1000;
      if (m_time2gen <= 0) m_time2gen = 1;
      onTimerTimeout();
    }
  }
  log_info_("ui", "keygen number %lld, elapsed %lld, estimated %lld, value = %d\n",
            time2gen, m_elapsedTime.elapsed() / 1000, m_time2gen / 1000, m_val);
}
