use super::code_action::apply_workspace_edit_editor_command;
use crate::context::*;
use crate::types::*;
use crate::util::file_path_to_uri;
use lsp_types::request::ExecuteCommand;
use lsp_types::*;

pub fn organize_imports(meta: EditorMeta, ctx: &mut Context) {
    let file_uri = file_path_to_uri(&meta.buffile);
    let file_uri: String = file_uri.as_str().into();

    let req_params = ctx
        .servers(&meta)
        .map(|(server_id, _)| {
            (
                server_id,
                vec![ExecuteCommandParams {
                    command: "java.edit.organizeImports".to_string(),
                    arguments: vec![serde_json::json!(file_uri)],
                    ..ExecuteCommandParams::default()
                }],
            )
        })
        .collect();

    ctx.call::<ExecuteCommand, _>(
        meta,
        RequestParams::Each(req_params),
        move |ctx, meta, results| {
            let response = match results.into_iter().find(|(_, v)| v.is_some()) {
                Some((_, result)) => result,
                None => None,
            };

            if let Some(response) = response {
                organize_imports_response(meta, serde_json::from_value(response).unwrap(), ctx);
            }
        },
    );
}

pub fn organize_imports_response(
    meta: EditorMeta,
    result: Option<WorkspaceEdit>,
    ctx: &mut Context,
) {
    let result = match result {
        Some(result) => result,
        None => return,
    };

    let select_cmd = apply_workspace_edit_editor_command(&result, false);

    ctx.exec(meta, select_cmd);
}
