//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================

#include <QApplication>
#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QSslSocket>
#include <QStringList>
#include <QTextStream>

#include "smtk/cumulus/jobspanel/mainwindow.h"
#include "smtk/newt/qtNewtInterface.h"
#include "smtk/newt/qtNewtLoginDialog.h"

#include <cstdio>

void printUsage();

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);
  QString url;
  QString altLogin; // username (with newt session id in local file)

  QStringList args = QCoreApplication::arguments();

  if (args.length() < 3)
  {
    printUsage();
    return EXIT_FAILURE;
  }

  for (QStringList::const_iterator it = args.constBegin() + 1, itEnd = args.constEnd(); it != itEnd;
       ++it)
  {
    if (*it == "-u" || *it == "--url")
    {
      url = *(++it);
      continue;
    }
    else if (*it == "-a" || *it == "--alt-login")
    {
      altLogin = *(++it);
      continue;
    }
    else if (*it == "-h" || *it == "-H" || *it == "--help" || *it == "-help")
    {
      printUsage();
      return EXIT_SUCCESS;
    }
    else
    {
      qWarning(qPrintable(QObject::tr("Unrecognized command line option: %s")), qPrintable(*it));
      printUsage();
      return EXIT_FAILURE;
    }
  }

  if (url.isEmpty())
  {
    printUsage();
    return EXIT_FAILURE;
  }

  if (!QSslSocket::supportsSsl())
  {
    QMessageBox::critical(
      NULL,
      QObject::tr("SSL support"),
      QObject::tr("SSL support is required, please ensure Qt has been compiled with SSL support."));
    return EXIT_FAILURE;
  }

  cumulus::MainWindow window;
  window.girderUrl(url);
  window.show();

  // Log in to NERSC
  newt::qtNewtInterface* newt = newt::qtNewtInterface::instance();

  if (!altLogin.isEmpty())
  {
    // For testing, uses session id stored in users home dir
    QString path = QDir::homePath() + QString("/.newt_sessionid");
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly))
    {
      qWarning() << "ABORT: Cannot bypass login because file ~/.newt_sessionid not found";
      window.close();
      return EXIT_FAILURE;
    }
    QTextStream qs(&file);
    QString newtSessionId = qs.readAll().trimmed();

    newt->mockLogin(altLogin, newtSessionId);
    window.authenticateGirder(newtSessionId);
  }
  else
  {
    // Use login dialog
    newt::qtNewtLoginDialog loginDialog;
    QObject::connect(
      &loginDialog,
      &newt::qtNewtLoginDialog::entered,
      [newt](const QString& username, const QString& password) {
        newt->login(username, password);
      });
    QObject::connect(
      &loginDialog, &newt::qtNewtLoginDialog::canceled, [&window]() { window.close(); });

    QObject::connect(
      newt, &newt::qtNewtInterface::loginComplete, [newt, &window](const QString username) {
        QString newtSessionId = newt->newtSessionId();
        window.authenticateGirder(newtSessionId);
      });
    QObject::connect(
      newt, &newt::qtNewtInterface::loginFail, [newt, &window](const QString message) {
        qCritical() << message;
        window.close();
        return EXIT_FAILURE;
      });

    loginDialog.exec();
  }

  return app.exec();
}

void printUsage()
{
  qWarning(
    "%s\n\n%s",
    qPrintable(QObject::tr("Usage: cumulus [options]")),
    qPrintable(QObject::tr("Options:")));

  const char* format = "      %3s %-20s   %s";

  qWarning(
    format, "-u,", "--url", qPrintable(QObject::tr("(Required) The URL for the cumulus server.")));
  qWarning(
    format,
    "-a,",
    "--alt-login",
    qPrintable(QObject::tr("Username for dev login (requires ~/.newt_sessionid file).")));
}
