// Copyright 2019 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#![deny(unsafe_op_in_unsafe_fn)]

use std::env::var;
use std::io::{self, stdout, Write};
use std::path::PathBuf;
use std::sync::atomic::{AtomicI32, Ordering};

use crosh::dispatcher::{CompletionResult, Dispatcher};
use crosh::{setup_dispatcher, util};
use libc::{c_int, c_void, fork, kill, pid_t, waitpid, SIGINT, SIGKILL, STDERR_FILENO, WIFSTOPPED};
use libchromeos::chromeos::is_dev_mode;
use libchromeos::handle_eintr_errno;
use libchromeos::panic_handler::install_memfd_handler;
use libchromeos::signal::{block_signal, unblock_signal};
use libchromeos::syslog;
use log::error;
use nix::sys::signal::Signal;
use rustyline::completion::Completer;
use rustyline::config::Configurer;
use rustyline::error::ReadlineError;
use rustyline::highlight::Highlighter;
use rustyline::hint::Hinter;
use rustyline::validate::Validator;
use rustyline::{CompletionType, Config, Context, Editor, Helper};

const HISTORY_FILENAME: &str = ".crosh_history";

// Program name.
const IDENT: &str = "crosh";

fn usage(error: bool) {
    let usage_msg = r#"Usage: crosh [options] [-- [args]]

Options:
  --dev(=true|false) Force dev mode commands to be available or not. '--dev' is
                     the same as '--dev=true'.
  --removable        Force removable (boot from USB/SD/etc...) mode.
  --usb              Same as above.
  --help, -h         Show this help string.
  -- <all args after this are a command to run>
                Execute a single command and exit.
"#;
    if error {
        eprintln!("{}", usage_msg)
    } else {
        println!("{}", usage_msg);
    }
}

fn intro() {
    println!(
        r#"Welcome to crosh, the ChromeOS developer shell.

If you got here by mistake, don't panic!  Just close this tab and carry on.

Type 'help' for a list of commands.

If you want to customize the look/behavior, you can use the options page.
Load it by using the Ctrl-Shift-P keyboard shortcut.
"#
    );
}

static COMMAND_RUNNING_PID: AtomicI32 = AtomicI32::new(-1);

// Provides integration with rustyline.
struct ReadLineHelper {
    dispatcher: Dispatcher,
}

impl ReadLineHelper {
    fn dispatcher(&self) -> &Dispatcher {
        &self.dispatcher
    }
}

impl Helper for ReadLineHelper {}

impl Completer for ReadLineHelper {
    type Candidate = String;

    fn complete(
        &self,
        line: &str,
        _pos: usize,
        _ctx: &Context<'_>,
    ) -> Result<(usize, Vec<String>), ReadlineError> {
        let tokens: Vec<String> = match shell_words::split(line) {
            Ok(v) => v,
            Err(shell_words::ParseError) => {
                // Don't provide completion if the given line ends in the middle of a token.
                return Ok((0, vec![line.to_string(); 1]));
            }
        };
        match self.dispatcher.complete_command(tokens) {
            CompletionResult::NoMatches => Ok((0, vec![line.to_string(); 1])),
            CompletionResult::SingleDiff(diff) => Ok((line.len(), vec![diff; 1])),
            CompletionResult::WholeTokenList(matches) => Ok((0, matches)),
        }
    }
}

impl Hinter for ReadLineHelper {
    type Hint = String;
}

impl Highlighter for ReadLineHelper {}

impl Validator for ReadLineHelper {}

// Forks off a child process which executes the command handler and waits for it to return.
// COMMAND_RUNNING_PID is updated to have the child process id so SIGINT can be sent.
fn handle_cmd(dispatcher: &Dispatcher, args: Vec<String>) -> Result<(), ()> {
    let pid: pid_t;
    unsafe {
        pid = fork();
    }
    if pid < 0 {
        return Err(());
    }
    // Handle the child thread case.
    if pid == 0 {
        clear_signal_handlers();
        dispatch_cmd(dispatcher, args);
    }

    COMMAND_RUNNING_PID.store(pid, Ordering::Release);

    let mut status: c_int = 1;
    // Safe because status is owned.
    // EINTR can be triggered by signals such as SIGWINCH.
    let code: pid_t = handle_eintr_errno!(unsafe { waitpid(pid, &mut status, 0) });
    // Safe because references are not used and the return code is checked.
    // This should only happen if the child process is ptraced.
    if WIFSTOPPED(status) && unsafe { kill(-pid, SIGKILL) } != 0 {
        error!("kill failed: {}", io::Error::last_os_error());
    }
    COMMAND_RUNNING_PID.store(-1, Ordering::Release);
    if code != pid {
        error!("waitpid failed: {}", io::Error::last_os_error());
        return Err(());
    }
    match status {
        0 => Ok(()),
        _ => Err(()),
    }
}

// Execute the specific command. This should be called in a child process.
fn dispatch_cmd(dispatcher: &Dispatcher, args: Vec<String>) {
    std::process::exit(match args.first().map(|s| &**s) {
        Some("help") => {
            let mut ret: i32 = 0;
            if args.len() == 2 {
                let list: [&str; 1] = [&args[1]];
                if dispatcher.help_string(&mut stdout(), Some(&list)).is_err() {
                    eprintln!("help: unknown command '{}'", &args[1]);
                    ret = 1;
                }
            } else {
                if args.len() > 1 {
                    eprintln!("ERROR: too many arguments");
                    ret = 1;
                }
                let list = ["help", "help_advanced", "ping", "top"];
                if dispatcher.help_string(&mut stdout(), Some(&list)).is_err() {
                    panic!();
                }
            }
            ret
        }
        Some("help_advanced") => {
            if args.len() > 1 {
                eprintln!("ERROR: too many arguments");
                1
            } else {
                if dispatcher.help_string(&mut stdout(), None).is_err() {
                    panic!();
                }
                0
            }
        }
        _ => match dispatcher.handle_command(args) {
            Ok(_) => 0,
            Err(e) => {
                error!("ERROR: {}", e);
                1
            }
        },
    });
}

// Handle Ctrl-c/SIGINT by sending a SIGINT to any running child process.
extern "C" fn sigint_handler(_: c_int) {
    let mut command_pid: i32 = COMMAND_RUNNING_PID.load(Ordering::Acquire);
    if command_pid >= 0 {
        let _ = stdout().flush();
        // Safe because command_pid belongs to a child process.
        if unsafe { kill(command_pid, SIGINT) } != 0 {
            let bytes = "kill failed.".as_bytes();
            // Safe because the length is checked and it is ok if it fails.
            unsafe { libc::write(STDERR_FILENO, bytes.as_ptr() as *const c_void, bytes.len()) };
        } else {
            command_pid = -1;
        }
    }
    COMMAND_RUNNING_PID.store(command_pid, Ordering::Release);
}

fn register_signal_handlers() {
    // Safe because sigint_handler is async-signal-safe.
    unsafe { util::set_signal_handlers(&[Signal::SIGINT], sigint_handler) };
    if let Err(err) = block_signal(Signal::SIGHUP) {
        error!("Failed to block SIGHUP: {}", err);
    }
}

fn clear_signal_handlers() {
    util::clear_signal_handlers(&[Signal::SIGINT]);
    if let Err(err) = unblock_signal(Signal::SIGHUP) {
        error!("Failed to unblock SIGHUP: {}", err);
    }
}

// Loop for getting each command from the user and dispatching it to the handler.
fn input_loop(dispatcher: Dispatcher) {
    let history_path = match var("HOME") {
        Ok(h) => {
            if h.is_empty() {
                None
            } else {
                Some(PathBuf::from(h).join(HISTORY_FILENAME))
            }
        }
        _ => None,
    };

    let helper = ReadLineHelper { dispatcher };

    let mut builder = Config::builder()
        .auto_add_history(true)
        .history_ignore_dups(true)
        .history_ignore_space(true)
        .completion_type(CompletionType::List);
    builder.set_max_history_size(4096);

    let config = builder.build();
    let mut editor = Editor::<ReadLineHelper>::with_config(config);
    editor.set_helper(Some(helper));

    if let Some(h) = history_path.as_ref() {
        match editor.load_history(h) {
            Ok(()) => {}
            Err(ReadlineError::Io(e)) => {
                if e.kind() != io::ErrorKind::NotFound {
                    error!("Error loading history: {}", e);
                }
            }
            Err(e) => {
                error!("Error loading history: {}", e);
            }
        }
    }

    let mut buffer = Vec::new();
    loop {
        let prompt = if buffer.is_empty() { "crosh" } else { "" };
        match editor.readline(&format!("\x1b[1;33m{}>\x1b[0m ", prompt)) {
            Ok(line) => {
                if line.ends_with('\\') {
                    buffer.push(line);
                    continue;
                }

                buffer.push(line);
                let tokens = match shell_words::split(&buffer.join("\n")) {
                    Ok(v) => v,
                    Err(shell_words::ParseError) => {
                        continue;
                    }
                };
                buffer.clear();

                if tokens.is_empty() {
                    continue;
                }
                if tokens[0] == "exit" || tokens[0] == "quit" {
                    break;
                }
                let _ = handle_cmd(editor.helper().unwrap().dispatcher(), tokens);
                if let Some(h) = history_path.as_ref() {
                    if let Err(e) = editor.save_history(h) {
                        error!("Error persisting history: {}", e);
                    }
                }
            }
            Err(ReadlineError::Interrupted) => {
                buffer.clear();
            }
            Err(ReadlineError::Io(ioe)) if ioe.kind() == std::io::ErrorKind::Interrupted => {
                buffer.clear();
            }
            Err(ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                error!("ReadLine error: {}", err);
                break;
            }
        }
    }
}

fn main() -> Result<(), ()> {
    install_memfd_handler();
    let mut args = std::env::args();

    if let Err(e) = syslog::init(IDENT.to_string(), true /* log_to_stderr */) {
        eprintln!("failed to initialize syslog: {}", e);
        return Err(());
    }

    if args.next().is_none() {
        error!("expected executable name.");
        return Err(());
    }

    let mut args_as_command = false;

    let mut command_args: Vec<String> = Vec::new();

    util::set_dev_commands_included(is_dev_mode().unwrap_or_else(|_| {
        error!("Could not locate 'crossystem'; assuming devmode is off.");
        false
    }));

    util::set_usb_commands_included(util::is_removable().unwrap_or_else(|_| {
        error!("Could not query filesystem; assuming not removable.");
        false
    }));

    for arg in args {
        if args_as_command {
            command_args.push(arg)
        } else {
            match arg.as_ref() {
                "--help" | "-h" => {
                    usage(false);
                    return Ok(());
                }
                "--dev" | "--dev=true" => {
                    util::set_dev_commands_included(true);
                }
                "--dev=false" => {
                    util::set_dev_commands_included(false);
                }
                "--removable" | "--usb" => {
                    util::set_usb_commands_included(true);
                }
                "--" => {
                    args_as_command = true;
                }
                _ => {
                    usage(true);
                    return Err(());
                }
            }
        }
    }

    let dispatcher = setup_dispatcher();

    if args_as_command {
        dispatch_cmd(&dispatcher, command_args);
        Ok(())
    } else {
        register_signal_handlers();

        intro();

        input_loop(dispatcher);
        Ok(())
    }
}
