pub mod v1;

use rocket::catch;
use serde::{Serialize};
use rocket::http::Status;

pub const ERR_MSG_MALFORMED_REQUEST: &str = "unable to parse the request body - is it valid JSON, using correct types?";
pub const ERR_MSG_MALFORMED_REQUEST_CODE: &str = "ERR_MALFORMED_REQUEST";

/*
TODO:
    /v1/auth/magic-link                         [done]
    /v1/auth/totp                               [done]
    /v1/auth/verify-magic-link                  [done]
    /v1/hosts/host-{id}/enrollment-code
    /v1/hosts/host-{id}/enrollment-code-check
    /v1/hosts/host-{id}
    /v1/roles/role-{id}
    /v1/feature-flags
    /v1/hosts
    /v1/networks
    /v1/roles
    /v1/signup                                  [done]
    /v1/totp-authenticators                     [done]
    /v1/verify-totp-authenticator               [done]
    /v1/dnclient
    /v2/enroll
    /v2/whoami
 */

#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
pub struct APIError {
    errors: Vec<APIErrorSingular>
}
#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
pub struct APIErrorSingular {
    code: String,
    message: String
}

macro_rules! error_handler {
    ($code: expr, $err: expr, $msg: expr) => {
        ::paste::paste! {
            #[catch($code)]
            pub fn [<handler_ $code>]() -> (Status, String) {
                (Status::from_code($code).unwrap(), format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{}\"}}]}}", $err, $msg))
            }
        }
    };
}
error_handler!(400, "ERR_MALFORMED_REQUEST", "unable to parse the request body, is it properly formatted?");
error_handler!(401, "ERR_AUTHENTICATION_REQUIRED", "this endpoint requires authentication but it was not provided");
error_handler!(403, "ERR_UNAUTHORIZED", "authorization was provided but it is expired or invalid");
error_handler!(404, "ERR_NOT_FOUND", "resource not found");
error_handler!(405, "ERR_METHOD_NOT_ALLOWED", "method not allowed for this endpoint");
error_handler!(422, "ERR_MALFORMED_REQUEST", "unable to parse the request body, is it properly formatted?");

error_handler!(500, "ERR_QL_QUERY_FAILED", "graphql query timed out");
error_handler!(501, "ERR_NOT_IMPLEMENTED", "query not supported by this version of graphql");
error_handler!(502, "ERR_PROXY_ERR", "servers under load, please try again later");
error_handler!(503, "ERR_SERVER_OVERLOADED", "servers under load, please try again later");
error_handler!(504, "ERR_PROXY_TIMEOUT", "servers under load, please try again later");
error_handler!(505, "ERR_CLIENT_UNSUPPORTED", "your version of dnclient is out of date, please update");
