use std::sync::Arc;
use std::future;
use log::info;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tower_lsp::jsonrpc::Result;

use crate::server::Backend;

#[derive(Clone)]
pub struct UpdateConfigurationApi;

#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct UpdateConfigurationParams {
    configs: Vec<UpdateConfigurationItem>,
    #[serde(rename = "configType")]
    config_type: String
}

#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
struct UpdateConfigurationItem {
    name: String,
    value: Value
}

impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (UpdateConfigurationParams, ), Result<()>> for UpdateConfigurationApi {
    type Future = future::Ready<Result<()>>;

    fn invoke(&self, _server: &'a Arc<Backend>, _params: (UpdateConfigurationParams, )) -> Self::Future {        
        let request_param = _params.0;
        let configs = request_param.configs;
        
        // 用于未来进行配置分区
        #[allow(unused)]
        let config_type = request_param.config_type;
        
        update_configuration(configs, &_server);
        future::ready(Ok(()))
    }
}

fn update_configuration(
    configs: Vec<UpdateConfigurationItem>,
    backend: &Arc<Backend>
) {
    let mut lsp_configuration = backend.server.srcs.lsp_configuration.write().unwrap();
    for config in configs {
        info!("name: {}, value: {}", config.name, config.value);
        lsp_configuration.insert(config.name, config.value);
    }
}