#include <QCoreApplication>
#include <QEventLoop>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QSslSocket>
#include <QTextStream>
#include <QTimer>
#include <QUrl>

int main(int argc, char** argv) {
  QCoreApplication application(argc, argv);
  const auto backends = QSslSocket::availableBackends();
  const bool secure_transport = QSslSocket::supportsSsl();
  const bool schannel_available = backends.contains(QStringLiteral("schannel"),
                                                     Qt::CaseInsensitive);
  QJsonArray backend_json;
  for (const auto& backend : backends) backend_json.append(backend);
  QJsonObject result{{"schema", "smartcut64-qt-tls-probe-v1"},
                     {"supports_ssl", secure_transport},
                     {"schannel_available", schannel_available},
                     {"active_backend", QSslSocket::activeBackend()},
                     {"available_backends", backend_json}};
  bool network_ok = true;
  if (argc == 2) {
    QNetworkAccessManager manager;
    QNetworkRequest request{QUrl::fromUserInput(QString::fromLocal8Bit(argv[1]))};
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
                         QNetworkRequest::NoLessSafeRedirectPolicy);
    auto* reply = manager.get(request);
    QEventLoop loop;
    QTimer timeout;
    timeout.setSingleShot(true);
    QObject::connect(&timeout, &QTimer::timeout, reply, &QNetworkReply::abort);
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    timeout.start(15000);
    loop.exec();
    const auto status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    const auto response = QJsonDocument::fromJson(reply->readAll());
    network_ok = reply->error() == QNetworkReply::NoError && status == 200 &&
                 response.isObject() && response.object().value("ok").toBool();
    result.insert("https_probe_ok", network_ok);
    result.insert("https_status", status);
    if (!network_ok) result.insert("https_error", reply->errorString());
    reply->deleteLater();
  } else if (argc != 1) {
    result.insert("argument_error", "Pass no argument or one HTTPS health URL.");
    network_ok = false;
  }
  QTextStream(stdout) << QJsonDocument(result).toJson(QJsonDocument::Compact) << '\n';
  return secure_transport && schannel_available && network_ok ? 0 : 1;
}
