// Module deals endpoints pertaining to admin-only actions

use hyper::{Response, Body};
use hyper::StatusCode;

use mysql_async::Pool;
use mysql_async::error::Error as SqlError;
use mysql_async::prelude::Queryable;

use serde_json::Value;

use crate::perms::ADMIN_PERMS;

macro_rules! get_target_id {
    ($obj:expr) => {
        match $obj.get("target-id") {
            Some(val) => val.as_u64(),
            None => None
        }
    }
}

async fn modify_perms(p: &Pool, uid: u64, new_perms: u64) -> Result<(), SqlError>{
    use mysql_async::params;
    let conn = p.get_conn().await?;
    conn.prep_exec(
        "UPDATE members SET permissions = :perms WHERE id = :id", 
        params!{
            "id" => uid,
            "perms" => new_perms
        }).await?;

    Ok(())
}

pub async fn new_admin(p: &Pool, response: &mut Response<Body>, params: Value) {
    // @requires: owner level permission as regular admins can have conflict of interests

    if let Some(uid) = get_target_id!(params) {
        let _ = modify_perms(p, uid, ADMIN_PERMS).await;
    }
    else {
        // this is likely the users fault providing shit ass json
        *response.status_mut() = StatusCode::BAD_REQUEST;
        *response.body_mut() = Body::from("Missing target user id");
    }
}

async fn update_member_permissions(p: &Pool, uid: u64, perms: u64) -> Result<(), SqlError>{
    use mysql_async::params;
    let conn = p.get_conn().await?;
    conn.prep_exec(
        "UPDATE members permissions = :perms WHERE id = :id",
        params!{
            "id" => uid,
            "perms" => perms
        }
        ).await?;

    Ok(())
}

pub async fn set_permissions(p: &Pool, response: &mut Response<Body>, params: Value) {
    // @requiresL: admin level permissions, admins can't touch other admins
    let tuid = get_target_id!(params);

    let new_perms = match params.get("permissions") {
        Some(val) => val.as_u64(),
        None => None
    };

    match (tuid, new_perms) {
        (Some(uid), Some(perms)) => {
            if let Ok(_) = update_member_permissions(p, uid, perms).await {
            }
        },
        _ => {
            *response.status_mut() = StatusCode::BAD_REQUEST;
            *response.body_mut() = Body::from("Missing one or more parameters");
        }
    }
}
