#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);
        std::generate(begin(token), end(token), std::ref(rbe));
        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) {}
}
