use std::io;
use std::io::BufRead;

use serde::{Deserialize, Serialize};
use tabled::{Table, Tabled};

///
pub fn read_input_or_default(q: &str, default: &str) -> String {
    println!("{}", q);
    let stdin = io::stdin();
    let mut render = stdin.lock();
    let mut input = String::new();
    render.read_line(&mut input).unwrap_or(0);
    if input.trim().is_empty() {
        default.to_string()
    } else {
        input.trim().to_string()
    }
}
pub fn read_input(q: &str) -> String {
    println!("{}", q);
    let stdin = io::stdin();
    let mut render = stdin.lock();
    let mut input = String::new();
    render.read_line(&mut input).expect("Failed to read line");
    input.trim().to_string()
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MmhConfig {
    pub servers: Vec<ServiceConfig>,
    pub sync_cmd: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ServiceConfig {
    pub name: String,
    pub host: String,
    pub port: u16,
    pub user: String,
    pub auth_type: AuthType,
    pub password: String,
    pub key_file: String,
}

#[derive(Tabled, Debug, Serialize, Deserialize)]
pub struct ServiceConfigView {
    pub id: usize,
    pub name: String,
    pub host: String,
    pub port: u16,
    pub user: String,
    pub auth_type: String,
}

#[derive(Tabled, Debug)]
pub struct ServicePingView {
    pub id: usize,
    pub name: String,
    pub host: String,
    pub port: u16,
    pub ping_result: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize, Tabled)]
pub enum AuthType {
    Pwd,
    Secret,
}

impl AuthType {
    pub(crate) fn as_str(&self) -> &str {
        match self {
            AuthType::Pwd => "pwd",
            AuthType::Secret => "secret",
        }
    }
}

//字符串转换AuthType
pub fn to_auth_type(s: &str) -> AuthType {
    match s {
        "pwd" => AuthType::Pwd,
        "secret" => AuthType::Secret,
        _ => panic!("auth type error"),
    }
}

//提供全局统一样式的 table输出
pub fn println_tabled<T: tabled::Tabled>(data_list: Vec<T>) {
    println!(
        "{}",
        Table::new(data_list)
            .with(tabled::settings::Style::modern())
            .to_string()
    )
}

// pub fn exec_script(cmd: String) {
//     let _ = std::process::Command::new("sh").arg("-c").arg(cmd).exec();
// }