#[allow(unused)]
use log::info;
use serde::{Deserialize, Serialize};
use crate::{server::LspServer, utils::command::is_command_valid};
use super::{AbstractLinterConfiguration, LinterStatus};
use ropey::Rope;
use tower_lsp::lsp_types::{Diagnostic, Url};

#[derive(Debug, Serialize, Deserialize)]
pub struct ModelsimConfiguration {
    pub language_id: String,
    pub linter: ModelsimLinter
}


#[derive(Debug, Serialize, Deserialize)]
pub struct ModelsimLinter {
    pub name: String,
    pub exe_name: String,
    /// 目前是否启动
    pub enabled: bool,
    pub path: String,
    pub args: Vec<String>,
}


impl ModelsimLinter {
    fn new(invoker: &str, args: Vec<String>) -> Self {
        Self {
            name: "modelsim".to_string(),
            exe_name: invoker.to_string(),
            enabled: false,
            path: invoker.to_string(),
            args,
        }
    }
}


impl AbstractLinterConfiguration for ModelsimConfiguration {
    fn new(language_id: &str, invoker: &str, args: Vec<String>) -> Self {
        ModelsimConfiguration {
            language_id: language_id.to_string(),
            linter: ModelsimLinter::new(invoker, args)
        }
    }
    
    fn provide_diagnostics(
        &self,
        uri: &Url,
        rope: &Rope,
        server: &LspServer
    ) -> Option<Vec<Diagnostic>> {
        let mut diagnostics = Vec::<Diagnostic>::new();

        Some(diagnostics)
    }

    fn get_windows_extension(&self) -> &str {
        "exe"
    }

    fn get_linter_path(&self) -> &str {
        &self.linter.path
    }

    fn linter_status(&self) -> LinterStatus {
        match self.language_id.as_str() {
            "verilog" => {
                let invoke_name = self.get_invoke_name("vlog");
                let available = is_command_valid(&invoke_name);
                LinterStatus {
                    tool_name: "vlog".to_string(),
                    available,
                    invoke_name
                }
            }

            "systemverilog" => {
                let invoke_name = self.get_invoke_name("vlog");
                let available = is_command_valid(&invoke_name);
                LinterStatus {
                    tool_name: "vlog".to_string(),
                    available,
                    invoke_name
                }
            }

            "vhdl" => {
                let invoke_name = self.get_invoke_name("vcom");
                let available = is_command_valid(&invoke_name);
                LinterStatus {
                    tool_name: "vcom".to_string(),
                    available,
                    invoke_name
                }
            }

            _ => {
                LinterStatus::default()
            }
        }
    }
}