/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

use std::path::PathBuf;

/// Selected once, so the advertised dialect and executed command cannot drift.
#[derive(Clone)]
pub(crate) enum ShellPlan {
    #[cfg(unix)]
    Posix { path: PathBuf, kind: PosixShell },
    #[cfg(windows)]
    Pwsh(PathBuf),
    #[cfg(windows)]
    WindowsPowerShell(PathBuf),
    #[cfg(windows)]
    Cmd(PathBuf),
}

impl ShellPlan {
    pub(crate) fn command(
        &self,
        cwd: &std::path::Path,
        source: &str,
        terminal: bool,
        login: bool,
    ) -> crate::Command {
        use crate::Command;
        match self {
            #[cfg(unix)]
            Self::Posix { path, .. } => {
                let _ = terminal;
                let mut command = Command::new(path, cwd);
                command.args([if login { "-lc" } else { "-c" }, source]);
                command
            }
            #[cfg(windows)]
            Self::Pwsh(path) | Self::WindowsPowerShell(path) => {
                let mut plan = Command::new(path, cwd);
                plan.arg("-NoLogo");
                if !login {
                    plan.arg("-NoProfile");
                }
                if !terminal {
                    plan.arg("-NonInteractive");
                }
                plan.args(["-Command", command::WRAPPER])
                    .env(command::SLOT, format!("{source}{}", command::EXIT));
                plan
            }
            #[cfg(windows)]
            Self::Cmd(path) => {
                let mut command = Command::new(path, cwd);
                command.raw_arg(format!("/d /s /c \"{source}\""));
                command
            }
        }
    }

    pub(crate) fn interactive(&self, cwd: &std::path::Path) -> (String, crate::pty::PtyCommand) {
        use crate::pty::PtyCommand;
        let (source, mut command) = match self {
            #[cfg(unix)]
            Self::Posix { path, .. } => {
                let source = "exec \"$SHELL\" -l";
                let mut command = PtyCommand::new(path, cwd);
                command.arg("-l").env("SHELL", path);
                (source.into(), command)
            }
            #[cfg(windows)]
            Self::Pwsh(path) | Self::WindowsPowerShell(path) => {
                let source = format!("& '{}' -NoLogo", path.to_string_lossy().replace('\'', "''"));
                let mut command = PtyCommand::new(path, cwd);
                command.arg("-NoLogo");
                (source, command)
            }
            #[cfg(windows)]
            Self::Cmd(path) => {
                let mut command = PtyCommand::new(path, cwd);
                command.args(["/d", "/q"]);
                ("%ComSpec% /d /q".into(), command)
            }
        };
        command
            .env("DISABLE_AUTO_UPDATE", "true")
            .env("DISABLE_UPDATE_PROMPT", "true");
        (source, command)
    }

    pub(crate) fn detect() -> Self {
        #[cfg(unix)]
        return select_posix(account_shell().map(PathBuf::from), find_posix);
        #[cfg(windows)]
        {
            fn find(name: &str, fallback: Option<PathBuf>) -> Option<PathBuf> {
                std::env::var_os("PATH")
                    .into_iter()
                    .flat_map(|path| std::env::split_paths(&path).collect::<Vec<_>>())
                    .map(|directory| directory.join(name))
                    .chain(fallback)
                    .find_map(|path| {
                        path.is_file()
                            .then(|| dunce::canonicalize(path).ok())
                            .flatten()
                    })
            }
            if let Some(path) = find(
                "pwsh.exe",
                std::env::var_os("ProgramFiles")
                    .map(|root| PathBuf::from(root).join(r"PowerShell\7\pwsh.exe")),
            ) {
                return Self::Pwsh(path);
            }
            let system = PathBuf::from(
                std::env::var_os("SystemRoot").unwrap_or_else(|| r"C:\Windows".into()),
            );
            if let Some(path) = find(
                "powershell.exe",
                Some(system.join(r"System32\WindowsPowerShell\v1.0\powershell.exe")),
            ) {
                return Self::WindowsPowerShell(path);
            }
            Self::Cmd(system.join(r"System32\cmd.exe"))
        }
    }

    pub(crate) fn guidance(&self) -> String {
        match self {
            #[cfg(unix)]
            Self::Posix { path, kind } => {
                format!(
                    "Commands use {}; write {} syntax. Login profiles load by default; set login=false to skip them.",
                    path.display(),
                    kind.syntax(),
                )
            }
            #[cfg(windows)]
            Self::Pwsh(_) => {
                "Commands use PowerShell 7 (pwsh); write PowerShell syntax. Set login=false to skip profiles.".into()
            }
            #[cfg(windows)]
            Self::WindowsPowerShell(_) => {
                "Commands use Windows PowerShell 5.1; write PowerShell 5.1-compatible syntax. Set login=false to skip profiles.".into()
            }
            #[cfg(windows)]
            Self::Cmd(_) => "Commands use cmd.exe; write cmd syntax, not bash syntax.".into(),
        }
    }
}

#[cfg(unix)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum PosixShell {
    Zsh,
    Bash,
    Sh,
}

#[cfg(unix)]
impl PosixShell {
    fn from_path(path: &std::path::Path) -> Option<Self> {
        match path.file_name()?.to_str()? {
            "zsh" => Some(Self::Zsh),
            "bash" => Some(Self::Bash),
            "sh" => Some(Self::Sh),
            _ => None,
        }
    }

    fn name(self) -> &'static str {
        match self {
            Self::Zsh => "zsh",
            Self::Bash => "bash",
            Self::Sh => "sh",
        }
    }

    fn syntax(self) -> &'static str {
        match self {
            Self::Zsh => "zsh",
            Self::Bash => "Bash",
            Self::Sh => "POSIX shell",
        }
    }
}

#[cfg(unix)]
fn executable(path: &std::path::Path) -> bool {
    use std::os::unix::fs::PermissionsExt;
    path.is_absolute()
        && std::fs::metadata(path)
            .is_ok_and(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
}

#[cfg(unix)]
fn find_posix(kind: PosixShell) -> Option<PathBuf> {
    std::env::var_os("PATH")
        .into_iter()
        .flat_map(|path| std::env::split_paths(&path).collect::<Vec<_>>())
        .map(|directory| directory.join(kind.name()))
        .chain(["/bin", "/usr/bin"].map(|directory| PathBuf::from(directory).join(kind.name())))
        .find(|path| executable(path))
}

#[cfg(unix)]
fn select_posix(
    account: Option<PathBuf>,
    mut find: impl FnMut(PosixShell) -> Option<PathBuf>,
) -> ShellPlan {
    if let Some(path) = account.filter(|path| executable(path))
        && let Some(kind) = PosixShell::from_path(&path)
    {
        return ShellPlan::Posix { path, kind };
    }
    let order = if cfg!(target_os = "macos") {
        [PosixShell::Zsh, PosixShell::Bash]
    } else {
        [PosixShell::Bash, PosixShell::Zsh]
    };
    for kind in order {
        if let Some(path) = find(kind) {
            return ShellPlan::Posix { path, kind };
        }
    }
    ShellPlan::Posix {
        path: "/bin/sh".into(),
        kind: PosixShell::Sh,
    }
}

#[cfg(unix)]
fn account_shell() -> Option<std::ffi::OsString> {
    use std::{ffi::CStr, os::unix::ffi::OsStrExt};
    let mut buffer = vec![0u8; 65_536];
    let mut entry = std::mem::MaybeUninit::<libc::passwd>::uninit();
    let mut result = std::ptr::null_mut();
    // SAFETY: output pointers and scratch storage remain live through copying
    // pw_shell; no borrowed libc account memory escapes this function.
    unsafe {
        if libc::getpwuid_r(
            libc::geteuid(),
            entry.as_mut_ptr(),
            buffer.as_mut_ptr().cast(),
            buffer.len(),
            &mut result,
        ) != 0
            || result.is_null()
        {
            return None;
        }
        let entry = entry.assume_init();
        if entry.pw_shell.is_null() {
            return None;
        }
        let bytes = CStr::from_ptr(entry.pw_shell).to_bytes();
        (!bytes.is_empty()).then(|| std::ffi::OsStr::from_bytes(bytes).to_owned())
    }
}

#[cfg(windows)]
pub(crate) mod command {
    use std::{os::windows::ffi::OsStrExt, path::Path};

    pub(super) const SLOT: &str = "__MAKA_RUNTIME_POWERSHELL_COMMAND";
    // A read-only TEMP can put Windows PowerShell in ConstrainedLanguage.
    // Invoke-Expression parses in the current language mode; unlike
    // ScriptBlock::Create it does not require FullLanguage merely to launch a
    // native command. Never override machine application-control policy.
    pub(super) const WRAPPER: &str = r#"
if ($ExecutionContext.SessionState.LanguageMode -eq 'FullLanguage') {
    $__makaUtf8 = [System.Text.UTF8Encoding]::new($false)
    [Console]::InputEncoding = $__makaUtf8
    [Console]::OutputEncoding = $__makaUtf8
    $OutputEncoding = $__makaUtf8
} else {
    & "$env:SystemRoot\System32\chcp.com" 65001 > $null
    $OutputEncoding = [System.Text.Encoding]::UTF8
}
$__makaCommandText = $env:__MAKA_RUNTIME_POWERSHELL_COMMAND
Remove-Item Env:\__MAKA_RUNTIME_POWERSHELL_COMMAND
Invoke-Expression $__makaCommandText
"#;
    pub(super) const EXIT: &str = "\n$__makaOk = $?\nif (-not $__makaOk) { if ($LASTEXITCODE -is [int] -and $LASTEXITCODE -ne 0) { exit $LASTEXITCODE } else { exit 1 } }";

    pub(crate) fn wide(path: &Path) -> std::io::Result<Vec<u16>> {
        let mut value: Vec<_> = path.as_os_str().encode_wide().collect();
        if value.contains(&0) {
            return Err(std::io::Error::other("NUL in process input"));
        }
        value.push(0);
        Ok(value)
    }

    pub(crate) fn quote(value: &str) -> String {
        let mut quoted = String::from("\"");
        let mut slashes = 0;
        for ch in value.chars() {
            if ch == '\\' {
                slashes += 1;
                continue;
            }
            quoted.extend(std::iter::repeat_n(
                '\\',
                if ch == '"' { slashes * 2 + 1 } else { slashes },
            ));
            quoted.push(ch);
            slashes = 0;
        }
        quoted.extend(std::iter::repeat_n('\\', slashes * 2));
        quoted.push('"');
        quoted
    }
}

#[cfg(all(test, unix))]
mod tests {
    use super::*;
    use std::os::unix::fs::PermissionsExt;

    #[test]
    fn account_selection_and_fallback_keep_guidance_pipes_and_pty_on_one_shell() {
        let directory = tempfile::tempdir().unwrap();
        let path = directory.path().join("bash");
        std::fs::write(&path, "#!/bin/sh\n").unwrap();
        std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o700)).unwrap();
        let selected = select_posix(Some(path.clone()), |_| panic!("account shell wins"));
        assert!(selected.guidance().contains(path.to_str().unwrap()));
        assert!(selected.guidance().contains("Bash syntax"));
        for terminal in [false, true] {
            for login in [false, true] {
                let command = selected.command(directory.path(), "echo ok", terminal, login);
                assert_eq!(command.executable, path);
                assert_eq!(command.args[0].as_ref(), if login { "-lc" } else { "-c" });
                assert_eq!(command.args[1].as_ref(), "echo ok");
            }
        }
        let (_, interactive) = selected.interactive(directory.path());
        assert_eq!(interactive.executable, path);
        assert_eq!(interactive.args[0].as_ref(), "-l");

        let unsupported = directory.path().join("fish");
        std::fs::copy(&path, &unsupported).unwrap();
        std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).unwrap();
        for account in [None, Some(path), Some(unsupported)] {
            let mut attempted = Vec::new();
            let selected = select_posix(account, |kind| {
                attempted.push(kind);
                None
            });
            let expected = if cfg!(target_os = "macos") {
                [PosixShell::Zsh, PosixShell::Bash]
            } else {
                [PosixShell::Bash, PosixShell::Zsh]
            };
            assert_eq!(attempted, expected);
            assert!(matches!(
                selected,
                ShellPlan::Posix {
                    kind: PosixShell::Sh,
                    ..
                }
            ));
        }
        for available in [PosixShell::Bash, PosixShell::Zsh] {
            let selected = select_posix(None, |kind| {
                (kind == available).then(|| PathBuf::from("/bin").join(kind.name()))
            });
            assert!(matches!(selected, ShellPlan::Posix { kind, .. } if kind == available));
        }
    }
}
