use axum::{
    extract::{Path, State},
    response::Redirect,
    routing::post,
    Router,
};

use crate::{http::error::AppError, node::stack::command, node::stack::StackCommand, AppState};

use axum::routing::get;

mod check;
mod create;
mod delete;
mod edit;
mod read;

macro_rules! stack_command {
    ($cmd: expr) => {
        move |Path(stack_name): Path<String>, State(state): State<AppState>| async move {
            command(&state.stack_dir, &stack_name, &state.arion_bin, $cmd).await?;
            Ok(Redirect::to("./")) as Result<Redirect, AppError>
        }
    };
}

pub(super) fn router() -> Router<AppState> {
    Router::new()
        .route(
            "/_/new",
            get(create::new_stack_page).post(create::create_stack),
        )
        .route("/_/check", post(check::check_stack_file))
        .route(
            "/:stack",
            get(|Path(stack_name): Path<String>| async move {
                Redirect::permanent(format!("{}/", &stack_name).as_str())
            }),
        )
        .route("/:stack/", get(read::get_one))
        .route("/:stack/start", post(stack_command!(StackCommand::Start)))
        .route(
            "/:stack/restart",
            post(stack_command!(StackCommand::Restart)),
        )
        .route("/:stack/stop", post(stack_command!(StackCommand::Stop)))
        .route("/:stack/down", post(stack_command!(StackCommand::Down)))
        .route("/:stack/edit", post(edit::edit_stack))
        .route(
            "/:stack/delete",
            get(delete::confirm_deletion_page).post(delete::delete_stack),
        )
    //.route("/:stack/history", get(get_stack_history))
}