#include <QApplication>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QTimer>
#include <QVBoxLayout>

#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/setup/reset.h"

#define NVME "/dev/nvme0n1"
#define USERDATA "/dev/disk/by-partlabel/userdata"

void Reset::doErase() {
  // best effort to wipe nvme
  std::system("sudo umount " NVME);
  std::system("yes | sudo mkfs.ext4 " NVME);

  int rm = std::system("sudo rm -rf /data/*");
  std::system("sudo umount " USERDATA);
  int fmt = std::system("yes | sudo mkfs.ext4 " USERDATA);

  if (rm == 0 || fmt == 0) {
    std::system("sudo reboot");
  }
  body->setText(tr("Reset failed. Reboot to try again."));
  rebootBtn->show();
}

void Reset::startReset() {
  body->setText(tr("Resetting device...\nThis may take up to a minute."));
  rejectBtn->hide();
  rebootBtn->hide();
  confirmBtn->hide();
#ifdef __aarch64__
  QTimer::singleShot(100, this, &Reset::doErase);
#endif
}

void Reset::confirm() {
  const QString confirm_txt = tr("Are you sure you want to reset your device?");
  if (body->text() != confirm_txt) {
    body->setText(confirm_txt);
  } else {
    startReset();
  }
}

Reset::Reset(ResetMode mode, QWidget *parent) : QWidget(parent) {
  QVBoxLayout *main_layout = new QVBoxLayout(this);
  main_layout->setContentsMargins(45, 220, 45, 45);
  main_layout->setSpacing(0);

  QLabel *title = new QLabel(tr("System Reset"));
  title->setStyleSheet("font-size: 90px; font-weight: 600;");
  main_layout->addWidget(title, 0, Qt::AlignTop | Qt::AlignLeft);

  main_layout->addSpacing(60);

  body = new QLabel(tr("Press confirm to erase all content and settings. Press cancel to resume boot."));
  body->setWordWrap(true);
  body->setStyleSheet("font-size: 80px; font-weight: light;");
  main_layout->addWidget(body, 1, Qt::AlignTop | Qt::AlignLeft);

  QHBoxLayout *blayout = new QHBoxLayout();
  main_layout->addLayout(blayout);
  blayout->setSpacing(50);

  rejectBtn = new QPushButton(tr("Cancel"));
  blayout->addWidget(rejectBtn);
  QObject::connect(rejectBtn, &QPushButton::clicked, QCoreApplication::instance(), &QCoreApplication::quit);

  rebootBtn = new QPushButton(tr("Reboot"));
  blayout->addWidget(rebootBtn);
#ifdef __aarch64__
  QObject::connect(rebootBtn, &QPushButton::clicked, [=]{
    std::system("sudo reboot");
  });
#endif

  confirmBtn = new QPushButton(tr("Confirm"));
  confirmBtn->setStyleSheet(R"(
    QPushButton {
      background-color: #465BEA;
    }
    QPushButton:pressed {
      background-color: #3049F4;
    }
  )");
  blayout->addWidget(confirmBtn);
  QObject::connect(confirmBtn, &QPushButton::clicked, this, &Reset::confirm);

  bool recover = mode == ResetMode::RECOVER;
  rejectBtn->setVisible(!recover);
  rebootBtn->setVisible(recover);
  if (recover) {
    body->setText(tr("Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device."));
  }

  // automatically start if we're just finishing up an ABL reset
  if (mode == ResetMode::FORMAT) {
    startReset();
  }

  setStyleSheet(R"(
    * {
      font-family: Inter;
      color: white;
      background-color: black;
    }
    QLabel {
      margin-left: 140;
    }
    QPushButton {
      height: 160;
      font-size: 55px;
      font-weight: 400;
      border-radius: 10px;
      background-color: #333333;
    }
    QPushButton:pressed {
      background-color: #444444;
    }
  )");
}

int main(int argc, char *argv[]) {
  ResetMode mode = ResetMode::USER_RESET;
  if (argc > 1) {
    if (strcmp(argv[1], "--recover") == 0) {
      mode = ResetMode::RECOVER;
    } else if (strcmp(argv[1], "--format") == 0) {
      mode = ResetMode::FORMAT;
    }
  }

  QApplication a(argc, argv);
  Reset reset(mode);
  setMainWindow(&reset);
  return a.exec();
}
