use std::collections::HashMap;
use std::ffi::OsStr;
use std::fmt::Debug;
use std::fs;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus, Output};

fn exec_command(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
    env: Option<&HashMap<String, String>>,
) -> Result<ExitStatus, String> {
    let status = get_command_inner(input, cwd, env)
        .spawn()
        .map_err(|e| command_error(input, &cwd, e))?
        .wait()
        .map_err(|e| command_error(input, &cwd, e))?;
    #[cfg(unix)]
    {
        if let Some(signal) = status.signal() {
            // In case the signal didn't kill the current process.
            return Err(command_error(input, &cwd, format!("Process received signal {signal}")));
        }
    }
    Ok(status)
}

pub(crate) fn get_command_inner(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
    env: Option<&HashMap<String, String>>,
) -> Command {
    let (cmd, args) = match input {
        [] => panic!("empty command"),
        [cmd, args @ ..] => (cmd, args),
    };
    let mut command = Command::new(cmd);
    command.args(args);
    if let Some(cwd) = cwd {
        command.current_dir(cwd);
    }
    if let Some(env) = env {
        command.envs(env.iter().map(|(k, v)| (k.as_str(), v.as_str())));
    }
    command
}

fn check_exit_status(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
    exit_status: ExitStatus,
    output: Option<&Output>,
    show_err: bool,
) -> Result<(), String> {
    if exit_status.success() {
        return Ok(());
    }
    let mut error = format!(
        "Command `{}`{} exited with status {:?}",
        input.iter().map(|s| s.as_ref().to_str().unwrap()).collect::<Vec<_>>().join(" "),
        cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display())).unwrap_or_default(),
        exit_status.code()
    );
    let input = input.iter().map(|i| i.as_ref()).collect::<Vec<&OsStr>>();
    if show_err {
        eprintln!("Command `{input:?}` failed");
    }
    if let Some(output) = output {
        let stdout = String::from_utf8_lossy(&output.stdout);
        if !stdout.is_empty() {
            error.push_str("\n==== STDOUT ====\n");
            error.push_str(&stdout);
        }
        let stderr = String::from_utf8_lossy(&output.stderr);
        if !stderr.is_empty() {
            error.push_str("\n==== STDERR ====\n");
            error.push_str(&stderr);
        }
    }
    Err(error)
}

fn command_error<D: Debug>(input: &[&dyn AsRef<OsStr>], cwd: &Option<&Path>, error: D) -> String {
    format!(
        "Command `{}`{} failed to run: {error:?}",
        input.iter().map(|s| s.as_ref().to_str().unwrap()).collect::<Vec<_>>().join(" "),
        cwd.as_ref()
            .map(|cwd| format!(" (running in folder `{}`)", cwd.display(),))
            .unwrap_or_default(),
    )
}

pub fn run_command(input: &[&dyn AsRef<OsStr>], cwd: Option<&Path>) -> Result<Output, String> {
    run_command_with_env(input, cwd, None)
}

pub fn run_command_with_env(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
    env: Option<&HashMap<String, String>>,
) -> Result<Output, String> {
    let output =
        get_command_inner(input, cwd, env).output().map_err(|e| command_error(input, &cwd, e))?;
    check_exit_status(input, cwd, output.status, Some(&output), true)?;
    Ok(output)
}

pub fn run_command_with_output(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
) -> Result<(), String> {
    let exit_status = exec_command(input, cwd, None)?;
    check_exit_status(input, cwd, exit_status, None, true)
}

pub fn run_command_with_output_and_env(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
    env: Option<&HashMap<String, String>>,
) -> Result<(), String> {
    let exit_status = exec_command(input, cwd, env)?;
    check_exit_status(input, cwd, exit_status, None, true)
}

#[cfg(not(unix))]
pub fn run_command_with_output_and_env_no_err(
    input: &[&dyn AsRef<OsStr>],
    cwd: Option<&Path>,
    env: Option<&HashMap<String, String>>,
) -> Result<(), String> {
    let exit_status = exec_command(input, cwd, env)?;
    check_exit_status(input, cwd, exit_status, None, false)
}

pub fn cargo_install(to_install: &str) -> Result<(), String> {
    let output = run_command(&[&"cargo", &"install", &"--list"], None)?;

    let to_install_needle = format!("{to_install} ");
    // cargo install --list returns something like this:
    //
    // mdbook-toc v0.8.0:
    //     mdbook-toc
    // rust-reduce v0.1.0:
    //     rust-reduce
    //
    // We are only interested into the command name so we only look for lines ending with `:`.
    if String::from_utf8(output.stdout)
        .unwrap()
        .lines()
        .any(|line| line.ends_with(':') && line.starts_with(&to_install_needle))
    {
        return Ok(());
    }
    // We voluntarily ignore this error.
    if run_command_with_output(&[&"cargo", &"install", &to_install], None).is_err() {
        println!("Skipping installation of `{to_install}`");
    }
    Ok(())
}

pub fn get_os_name() -> Result<String, String> {
    let output = run_command(&[&"uname"], None)?;
    let name = std::str::from_utf8(&output.stdout).unwrap_or("").trim().to_string();
    if !name.is_empty() { Ok(name) } else { Err("Failed to retrieve the OS name".to_string()) }
}

#[derive(Default, PartialEq)]
pub struct RustcVersionInfo {
    pub short: String,
    pub version: String,
    pub host: Option<String>,
    pub commit_hash: Option<String>,
    pub commit_date: Option<String>,
}

pub fn rustc_toolchain_version_info(toolchain: &str) -> Result<RustcVersionInfo, String> {
    rustc_version_info_inner(None, Some(toolchain))
}

pub fn rustc_version_info(rustc: Option<&str>) -> Result<RustcVersionInfo, String> {
    rustc_version_info_inner(rustc, None)
}

fn rustc_version_info_inner(
    rustc: Option<&str>,
    toolchain: Option<&str>,
) -> Result<RustcVersionInfo, String> {
    let output = if let Some(toolchain) = toolchain {
        run_command(&[&rustc.unwrap_or("rustc"), &toolchain, &"-vV"], None)
    } else {
        run_command(&[&rustc.unwrap_or("rustc"), &"-vV"], None)
    }?;
    let content = std::str::from_utf8(&output.stdout).unwrap_or("");

    let mut info = RustcVersionInfo::default();
    let mut lines = content.split('\n');
    info.short = match lines.next() {
        Some(s) => s.to_string(),
        None => return Err("failed to retrieve rustc version".to_string()),
    };

    for line in lines.map(|line| line.trim()) {
        match line.split_once(':') {
            Some(("host", data)) => info.host = Some(data.trim().to_string()),
            Some(("release", data)) => info.version = data.trim().to_string(),
            Some(("commit-hash", data)) => info.commit_hash = Some(data.trim().to_string()),
            Some(("commit-date", data)) => info.commit_date = Some(data.trim().to_string()),
            _ => {}
        }
    }
    if info.version.is_empty() {
        Err("failed to retrieve rustc version".to_string())
    } else {
        Ok(info)
    }
}

pub fn get_toolchain() -> Result<String, String> {
    let content = match fs::read_to_string("rust-toolchain") {
        Ok(content) => content,
        Err(_) => return Err("No `rust-toolchain` file found".to_string()),
    };
    match content
        .split('\n')
        .map(|line| line.trim())
        .filter(|line| !line.is_empty())
        .filter_map(|line| {
            if !line.starts_with("channel") {
                return None;
            }
            line.split('"').nth(1)
        })
        .next()
    {
        Some(toolchain) => Ok(toolchain.to_string()),
        None => Err("Couldn't find `channel` in `rust-toolchain` file".to_string()),
    }
}

pub struct CloneResult {
    pub ran_clone: bool,
    pub repo_name: String,
    pub repo_dir: String,
}

fn git_clone_inner(
    to_clone: &str,
    dest: &Path,
    shallow_clone: bool,
    repo_name: String,
) -> Result<CloneResult, String> {
    if dest.is_dir() {
        return Ok(CloneResult {
            ran_clone: false,
            repo_name,
            repo_dir: dest.display().to_string(),
        });
    }

    let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"git", &"clone", &to_clone, &dest];
    if shallow_clone {
        command.push(&"--depth");
        command.push(&"1");
    }
    run_command_with_output(&command, None)?;
    Ok(CloneResult { ran_clone: true, repo_name, repo_dir: dest.display().to_string() })
}

fn get_repo_name(url: &str) -> String {
    let repo_name = url.split('/').next_back().unwrap();
    match repo_name.strip_suffix(".git") {
        Some(n) => n.to_string(),
        None => repo_name.to_string(),
    }
}

pub fn git_clone(
    to_clone: &str,
    dest: Option<&Path>,
    shallow_clone: bool,
) -> Result<CloneResult, String> {
    let repo_name = get_repo_name(to_clone);
    let tmp: PathBuf;

    let dest = match dest {
        Some(dest) => dest,
        None => {
            tmp = repo_name.clone().into();
            &tmp
        }
    };
    git_clone_inner(to_clone, dest, shallow_clone, repo_name)
}

pub fn create_dir<P: AsRef<Path>>(path: P) -> Result<(), String> {
    fs::create_dir_all(&path).map_err(|error| {
        format!("Failed to create directory `{}`: {:?}", path.as_ref().display(), error)
    })
}

/// This function differs from `git_clone` in how it handles *where* the repository will be cloned.
/// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is
/// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into
/// `a/b`.
pub fn git_clone_root_dir(
    to_clone: &str,
    dest_parent_dir: &Path,
    shallow_clone: bool,
) -> Result<CloneResult, String> {
    let repo_name = get_repo_name(to_clone);

    git_clone_inner(to_clone, &dest_parent_dir.join(&repo_name), shallow_clone, repo_name)
}

pub fn walk_dir<P, D, F>(
    dir: P,
    dir_cb: &mut D,
    file_cb: &mut F,
    recursive: bool,
) -> Result<(), String>
where
    P: AsRef<Path>,
    D: FnMut(&Path) -> Result<(), String>,
    F: FnMut(&Path) -> Result<(), String>,
{
    let dir = dir.as_ref();
    for entry in fs::read_dir(dir)
        .map_err(|error| format!("Failed to read dir `{}`: {:?}", dir.display(), error))?
    {
        let entry = entry
            .map_err(|error| format!("Failed to read entry in `{}`: {:?}", dir.display(), error))?;
        let entry_path = entry.path();
        if entry_path.is_dir() {
            dir_cb(&entry_path)?;
            if recursive {
                walk_dir(entry_path, dir_cb, file_cb, recursive)?; // Recursive call
            }
        } else {
            file_cb(&entry_path)?;
        }
    }
    Ok(())
}

pub fn split_args(args: &str) -> Result<Vec<String>, String> {
    let mut out = Vec::new();
    let mut start = 0;
    let args = args.trim();
    let mut iter = args.char_indices().peekable();

    while let Some((pos, c)) = iter.next() {
        if c == ' ' {
            out.push(args[start..pos].to_string());
            let mut found_start = false;
            while let Some((pos, c)) = iter.peek() {
                if *c != ' ' {
                    start = *pos;
                    found_start = true;
                    break;
                } else {
                    iter.next();
                }
            }
            if !found_start {
                return Ok(out);
            }
        } else if c == '"' || c == '\'' {
            let end = c;
            let mut found_end = false;
            while let Some((_, c)) = iter.next() {
                if c == end {
                    found_end = true;
                    break;
                } else if c == '\\' {
                    // We skip the escaped character.
                    iter.next();
                }
            }
            if !found_end {
                return Err(format!("Didn't find `{}` at the end of `{}`", end, &args[start..]));
            }
        } else if c == '\\' {
            // We skip the escaped character.
            iter.next();
        }
    }
    let s = args[start..].trim();
    if !s.is_empty() {
        out.push(s.to_string());
    }
    Ok(out)
}

pub fn remove_file<P: AsRef<Path> + ?Sized>(file_path: &P) -> Result<(), String> {
    std::fs::remove_file(file_path).map_err(|error| {
        format!("Failed to remove `{}`: {:?}", file_path.as_ref().display(), error)
    })
}

pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> Result<(), String> {
    #[cfg(windows)]
    let symlink = std::os::windows::fs::symlink_file;
    #[cfg(not(windows))]
    let symlink = std::os::unix::fs::symlink;

    symlink(&original, &link).map_err(|err| {
        format!(
            "failed to create a symlink `{}` to `{}`: {:?}",
            original.as_ref().display(),
            link.as_ref().display(),
            err,
        )
    })
}

pub fn get_sysroot_dir() -> PathBuf {
    Path::new(crate::BUILD_DIR).join("build_sysroot")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_split_args() {
        // Missing `"` at the end.
        assert!(split_args("\"tada").is_err());
        // Missing `'` at the end.
        assert!(split_args("\'tada").is_err());

        assert_eq!(
            split_args("a \"b\" c"),
            Ok(vec!["a".to_string(), "\"b\"".to_string(), "c".to_string()])
        );
        // Trailing whitespace characters.
        assert_eq!(
            split_args("    a    \"b\" c    "),
            Ok(vec!["a".to_string(), "\"b\"".to_string(), "c".to_string()])
        );
    }
}
