/*
    Hurry Curry! - a game about cooking
    Copyright 2024 metamuffin
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, version 3 of the License only.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
*/
use crate::Registry;
use anyhow::Result;
use hurrycurry_protocol::registry::Entry;
use rocket::{
    get,
    http::{Header, MediaType},
    request::{self, FromRequest, Outcome},
    response::{
        self,
        content::{RawHtml, RawJson},
        Responder,
    },
    Either, Request, State,
};
use std::sync::Arc;
use tokio::sync::RwLock;
#[get("/v1/list")]
pub(super) async fn r_list(
    registry: &State>>,
    json: AcceptJson,
) -> Cors>, RawHtml>>> {
    Cors(if json.0 {
        Either::Left(RawJson(registry.read().await.json_response.clone()))
    } else {
        Either::Right(RawHtml(registry.read().await.html_response.clone()))
    })
}
pub(super) fn generate_json_list(entries: &[Entry]) -> Result> {
    Ok(serde_json::to_string(&entries)?.into())
}
pub(super) fn generate_html_list(entries: &[Entry]) -> Result> {
    Ok(ListPage { entries }.to_string().into())
}
markup::define!(
    ListPage<'a>(entries: &'a [Entry]) {
        @markup::doctype()
        html {
            head {
                title {
                    "Hurry Curry! Server Registry"
                }
            }
            body {
                table {
                    tr { th {"Server"} th { "Players" } th { "Protocol" } }
                    @for e in *entries { tr {
                        td { details {
                            summary { @e.name }
                            ul { @for a in &e.address { li { @a } }}
                        } }
                        td { @e.players_online }
                        td { @e.version.0 "." @e.version.1 }
                    }}
                }
            }
        }
    }
);
pub struct AcceptJson(bool);
impl<'r> FromRequest<'r> for AcceptJson {
    type Error = ();
    fn from_request<'life0, 'async_trait>(
        request: &'r Request<'life0>,
    ) -> ::core::pin::Pin<
        Box<
            dyn ::core::future::Future