#pragma once

#include <pam_authenticate.hpp>
#include <persistent_data_middleware.hpp>
#include <webassets.hpp>
#include <random>
#include <crow/app.h>
#include <crow/http_codes.h>
#include <crow/http_request.h>
#include <crow/http_response.h>
#include <boost/bimap.hpp>
#include <boost/container/flat_set.hpp>

namespace crow {

namespace TokenAuthorization {

class Middleware {
 public:
  struct context {
    const crow::PersistentData::UserSession* session;
  };

  void before_handle(crow::request& req, response& res, context& ctx) {
    std::string auth_header = req.get_header_value("Authorization");
    if (auth_header != "") {
      // Reject any kind of auth other than basic or token
      if (boost::starts_with(auth_header, "Basic ")) {
        ctx.session = perform_basic_auth(auth_header);
      } else if (boost::starts_with(auth_header, "Token ")) {
        ctx.session = perform_token_auth(auth_header);
      }
    } else if (req.headers.count("X-Auth-Token") == 1) {
      ctx.session = perform_xtoken_auth(req);
    } else if (req.headers.count("Cookie") == 1) {
      ctx.session = perform_cookie_auth(req);
    }

    if (ctx.session == nullptr && !is_on_whitelist(req)) {
      CROW_LOG_WARNING << "[AuthMiddleware] authorization failed";
      res.code = static_cast<int>(HttpRespCode::UNAUTHORIZED);
      res.add_header("WWW-Authenticate", "Basic");
      res.end();
      return;
    }

    // TODO get user privileges here and propagate it via MW context
    // else let the request continue unharmed
  }

  template <typename AllContext>
  void after_handle(request& req, response& res, context& ctx,
                    AllContext& allctx) {
    // TODO(ed) THis should really be handled by the persistent data middleware,
    // but because it is upstream, it doesn't have access to the session
    // information.  Should the data middleware persist the current user
    // session?
    if (ctx.session != nullptr &&
        ctx.session->persistence ==
            crow::PersistentData::PersistenceType::SINGLE_REQUEST) {
      PersistentData::session_store->remove_session(ctx.session);
    }
  }

 private:
  const crow::PersistentData::UserSession* perform_basic_auth(
      const std::string& auth_header) const {
    CROW_LOG_DEBUG << "[AuthMiddleware] Basic authentication";

    std::string auth_data;
    std::string param = auth_header.substr(strlen("Basic "));
    if (!crow::utility::base64_decode(param, auth_data)) {
      return nullptr;
    }
    std::size_t separator = auth_data.find(':');
    if (separator == std::string::npos) {
      return nullptr;
    }

    std::string user = auth_data.substr(0, separator);
    separator += 1;
    if (separator > auth_data.size()) {
      return nullptr;
    }
    std::string pass = auth_data.substr(separator);

    CROW_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;

    if (!pam_authenticate_user(user, pass)) {
      return nullptr;
    }

    // TODO(ed) generate_user_session is a little expensive for basic
    // auth, as it generates some random identifiers that will never be
    // used.  This should have a "fast" path for when user tokens aren't
    // needed.
    // This whole flow needs to be revisited anyway, as we can't be
    // calling directly into pam for every request
    return &(PersistentData::session_store->generate_user_session(
        user, crow::PersistentData::PersistenceType::SINGLE_REQUEST));
  }

  const crow::PersistentData::UserSession* perform_token_auth(
      const std::string& auth_header) const {
    CROW_LOG_DEBUG << "[AuthMiddleware] Token authentication";

    std::string token = auth_header.substr(strlen("Token "));
    auto session = PersistentData::session_store->login_session_by_token(token);
    return session;
  }

  const crow::PersistentData::UserSession* perform_xtoken_auth(
      const crow::request& req) const {
    CROW_LOG_DEBUG << "[AuthMiddleware] X-Auth-Token authentication";

    auto& token = req.get_header_value("X-Auth-Token");
    auto session = PersistentData::session_store->login_session_by_token(token);
    return session;
  }

  const crow::PersistentData::UserSession* perform_cookie_auth(
      const crow::request& req) const {
    CROW_LOG_DEBUG << "[AuthMiddleware] Cookie authentication";

    auto& cookie_value = req.get_header_value("Cookie");

    auto start_index = cookie_value.find("SESSION=");
    if (start_index == std::string::npos) {
      return nullptr;
    }
    start_index += sizeof("SESSION=") - 1;
    auto end_index = cookie_value.find(";", start_index);
    if (end_index == std::string::npos) {
      end_index = cookie_value.size();
    }
    std::string auth_key =
        cookie_value.substr(start_index, end_index - start_index);

    const crow::PersistentData::UserSession* session =
        PersistentData::session_store->login_session_by_token(auth_key);
    if (session == nullptr) {
      return nullptr;
    }

    // RFC7231 defines methods that need csrf protection
    if (req.method != "GET"_method) {
      const std::string& csrf = req.get_header_value("X-XSRF-TOKEN");
      // Make sure both tokens are filled
      if (csrf.empty() || session->csrf_token.empty()) {
        return nullptr;
      }
      // Reject if csrf token not available
      if (csrf != session->csrf_token) {
        return nullptr;
      }
    }
    return session;
  }

  // checks if request can be forwarded without authentication
  bool is_on_whitelist(const crow::request& req) const {
    // it's allowed to GET root node without authentication
    if ("GET"_method == req.method) {
      if (req.url == "/redfish/v1") {
        return true;
      } else if (crow::webassets::routes.find(req.url) !=
                 crow::webassets::routes.end()) {
        return true;
      }
    }

    // it's allowed to POST on session collection & login without authentication
    if ("POST"_method == req.method) {
      if ((req.url == "/redfish/v1/SessionService/Sessions") ||
          (req.url == "/login") || (req.url == "/logout")) {
        return true;
      }
    }

    return false;
  }
};

// TODO(ed) see if there is a better way to allow middlewares to request
// routes.
// Possibly an init function on first construction?
template <typename... Middlewares>
void request_routes(Crow<Middlewares...>& app) {
  static_assert(
      black_magic::contains<PersistentData::Middleware, Middlewares...>::value,
      "TokenAuthorization middleware must be enabled in app to use "
      "auth routes");
  CROW_ROUTE(app, "/login")
      .methods(
          "POST"_method)([&](const crow::request& req, crow::response& res) {
        std::string content_type;
        auto content_type_it = req.headers.find("content-type");
        if (content_type_it != req.headers.end()) {
          content_type = content_type_it->second;
          boost::algorithm::to_lower(content_type);
        }
        const std::string* username;
        const std::string* password;
        bool looks_like_ibm = false;


        // This object needs to be declared at this scope so the strings within
        // it are not destroyed before we can use them
        nlohmann::json login_credentials;
        // Check if auth was provided by a payload
        if (content_type == "application/json") {
          login_credentials = nlohmann::json::parse(req.body, nullptr, false);
          if (login_credentials.is_discarded()) {
            res.code = 400;
            res.end();
            return;
          }
          // check for username/password in the root object
          // THis method is how intel APIs authenticate
          auto user_it = login_credentials.find("username");
          auto pass_it = login_credentials.find("password");
          if (user_it != login_credentials.end() &&
              pass_it != login_credentials.end()) {
            username = user_it->get_ptr<const std::string*>();
            password = pass_it->get_ptr<const std::string*>();
          } else {
            // Openbmc appears to push a data object that contains the same
            // keys (username and password), attempt to use that
            auto data_it = login_credentials.find("data");
            if (data_it != login_credentials.end()) {
              // Some apis produce an array of value ["username",
              // "password"]
              if (data_it->is_array()) {
                if (data_it->size() == 2) {
                  username = (*data_it)[0].get_ptr<const std::string*>();
                  password = (*data_it)[1].get_ptr<const std::string*>();
                  looks_like_ibm = true;
                }
              } else if (data_it->is_object()) {
                auto user_it = data_it->find("username");
                auto pass_it = data_it->find("password");
                if (user_it != data_it->end() && pass_it != data_it->end()) {
                  username = user_it->get_ptr<const std::string*>();
                  password = pass_it->get_ptr<const std::string*>();
                }
              }
            }
          }
        } else {
          // check if auth was provided as a query string
          auto user_it = req.headers.find("username");
          auto pass_it = req.headers.find("password");
          if (user_it != req.headers.end() && pass_it != req.headers.end()) {
            username = &user_it->second;
            password = &pass_it->second;
          }
        }

        if (username != nullptr && !username->empty() && password != nullptr &&
            !password->empty()) {
          if (!pam_authenticate_user(*username, *password)) {
            res.code = res.code = static_cast<int>(HttpRespCode::UNAUTHORIZED);
          } else {
            auto& session =
                PersistentData::session_store->generate_user_session(*username);

            if (looks_like_ibm) {
              // IBM requires a very specific login structure, and doesn't
              // actually look at the status code.  TODO(ed).... Fix that
              // upstream
              nlohmann::json ret{{"data", "User '" + *username + "' logged in"},
                                 {"message", "200 OK"},
                                 {"status", "ok"}};
              res.add_header("Set-Cookie", "XSRF-TOKEN=" + session.csrf_token);
              res.add_header("Set-Cookie", "SESSION=" + session.session_token +
                                               "; Secure; HttpOnly");

              res.write(ret.dump());
            } else {
              // if content type is json, assume json token
              nlohmann::json ret{{"token", session.session_token}};

              res.write(ret.dump());
              res.add_header("Content-Type", "application/json");
            }
          }

        } else {
          res.code = static_cast<int>(HttpRespCode::BAD_REQUEST);
        }
        res.end();
      });

  CROW_ROUTE(app, "/logout")
      .methods("POST"_method)(
          [&](const crow::request& req, crow::response& res) {
            auto& session =
                app.template get_context<TokenAuthorization::Middleware>(req)
                    .session;
            if (session != nullptr) {
              PersistentData::session_store->remove_session(session);
            }
            res.code = static_cast<int>(HttpRespCode::OK);
            res.end();
            return;

          });
}
}  // namespace TokenAuthorization
}  // namespace crow
