#include <boost/algorithm/string/predicate.hpp>
#include <random>
#include <unordered_map>

#include <crow/logging.h>
#include <base64.hpp>
#include <token_authorization_middleware.hpp>

namespace crow {

using random_bytes_engine =
    std::independent_bits_engine<std::default_random_engine, CHAR_BIT,
                                 unsigned char>;

TokenAuthorizationMiddleware::TokenAuthorizationMiddleware()
    : auth_token2(""){

      };

void TokenAuthorizationMiddleware::before_handle(crow::request& req,
                                                 response& res, context& ctx) {
  auto return_unauthorized = [&req, &res]() {
    res.code = 401;
    res.end();
  };

  auto return_bad_request = [&req, &res]() {
    res.code = 400;
    res.end();
  };

  LOG(DEBUG) << "Token Auth Got route " << req.url;

  if (req.url == "/" || boost::starts_with(req.url, "/static/")) {
    // TODO this is total hackery to allow the login page to work before the
    // user is authenticated.  Also, it will be quite slow for all pages instead
    // of a one time hit for the whitelist entries.  Ideally, this should be
    // done
    // in the url router handler, with tagged routes for the whitelist entries.
    // Another option would be to whitelist a minimal
    return;
  }

  if (req.url == "/login") {
    if (req.method != HTTPMethod::POST) {
      return_unauthorized();
      return;
    } else {
      auto login_credentials = crow::json::load(req.body);
      if (!login_credentials) {
        return_bad_request();
        return;
      }
      if (!login_credentials.has("username") ||
          !login_credentials.has("password")) {
        return_bad_request();
        return;
      }
      auto username = login_credentials["username"].s();
      auto password = login_credentials["password"].s();

      // TODO(ed) pull real passwords from PAM
      if (username == "dude" && password == "dude") {
        // TODO(ed) the RNG should be initialized at start, not every time we
        // want a token
        std::random_device rand;
        random_bytes_engine rbe;
        std::string token('a', 20);
        // TODO(ed) for some reason clang-tidy finds a divide by zero error in
        // cstdlibc here
        // commented out for now.  Needs investigation
        std::generate(begin(token), end(token), std::ref(rbe));  // NOLINT
        std::string encoded_token;
        base64::base64_encode(token, encoded_token);
        ctx.auth_token = encoded_token;
        this->auth_token2 = encoded_token;
        crow::json::wvalue x;
        auto auth_token = ctx.auth_token;
        x["token"] = auth_token;

        res.write(json::dump(x));
        res.add_header("Content-Type", "application/json");
        res.end();
      } else {
        return_unauthorized();
        return;
      }
    }

  } else if (req.url == "/logout") {
    this->auth_token2 = "";
    res.code = 200;
    res.end();
  } else {  // Normal, non login, non static file request
    // Check to make sure we're logged in
    if (this->auth_token2.empty()) {
      return_unauthorized();
      return;
    }
    // Check for an authorization header, reject if not present
    if (req.headers.count("Authorization") != 1) {
      return_unauthorized();
      return;
    }

    std::string auth_header = req.get_header_value("Authorization");
    // If the user is attempting any kind of auth other than token, reject
    if (!boost::starts_with(auth_header, "Token ")) {
      return_unauthorized();
      return;
    }

    // TODO(ed), use span here instead of constructing a new string
    if (auth_header.substr(6) != this->auth_token2) {
      return_unauthorized();
      return;
    }
    // else let the request continue unharmed
  }
}

void TokenAuthorizationMiddleware::after_handle(request& req, response& res,
                                                context& ctx) {}
}
