// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use anyhow::{anyhow, bail, Result};
use directories::{BaseDirs, ProjectDirs};
use erased_serde::Serialize;
use log::LevelFilter;
use nix::sys::signal::{self, Signal};
use nix::unistd::{dup2, setsid, Pid};
use std::env::{self, args_os, ArgsOs};
use std::ffi::OsString;
use std::fs::{self, read_to_string, File};
use std::io::{self, ErrorKind, Write};
use std::iter::{IntoIterator, Iterator};
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
use std::process::{self, ChildStdout, Command, Stdio};
use std::str::FromStr;
use std::time::Duration;
use structopt::StructOpt;

use opentitanlib::backend;
use opentitanlib::proxy::SessionHandler;

#[derive(Debug, StructOpt)]
#[structopt(
    name = "opentitansession",
    about = "A tool for interacting with OpenTitan chips."
)]
struct Opts {
    #[structopt(
        long,
        default_value = "config",
        help = "Filename of a default flagsfile.  Relative to $XDG_CONFIG_HOME/opentitantool."
    )]
    rcfile: PathBuf,

    #[structopt(long, default_value = "off")]
    logging: LevelFilter,

    #[structopt(flatten)]
    backend_opts: backend::BackendOpts,

    #[structopt(
        long,
        help = "Stop a running session, optionally combine with --listen_port for disambiguation"
    )]
    stop: bool,

    #[structopt(
        long,
        help = "Optional, defaults to 9900 or nearest higher available port."
    )]
    listen_port: Option<u16>,

    #[structopt(long, help = "Start session, staying in foreground (do not daemonize)")]
    debug: bool,

    #[structopt(
        long,
        help = "Internal, used to tell the child process run as a daemon."
    )]
    child: bool,
}

// Given some existing option configuration, maybe re-evaluate command
// line options by reading an `rcfile`.
fn parse_command_line(opts: Opts, mut args: ArgsOs) -> Result<Opts> {
    // Initialize the logger if the user requested the non-defualt option.
    let logging = opts.logging;
    if logging != LevelFilter::Off {
        env_logger::Builder::from_default_env()
            .filter(None, opts.logging)
            .init();
    }
    if opts.rcfile.as_os_str().is_empty() {
        // No rcfile to parse.
        return Ok(opts);
    }

    // Construct the rcfile path based on the user's config directory
    // (ie: $HOME/.config/opentitantool/<filename>).
    let rcfile = if let Some(base) = ProjectDirs::from("org", "opentitan", "opentitantool") {
        base.config_dir().join(&opts.rcfile)
    } else {
        opts.rcfile
    };

    // argument[0] is the executable name.
    let mut arguments = vec![args.next().unwrap()];

    // Read in the rcfile and extend the argument list.
    match read_to_string(&rcfile) {
        Ok(content) => {
            for line in content.split('\n') {
                // Strip basic comments as shellwords won't handle comments.
                let (line, _) = line.split_once('#').unwrap_or((line, ""));
                arguments.extend(shellwords::split(line)?.iter().map(OsString::from));
            }
            Ok(())
        }
        Err(e) if e.kind() == ErrorKind::NotFound => {
            log::warn!("Could not read {:?}. Ignoring.", rcfile);
            Ok(())
        }
        Err(e) => Err(anyhow::Error::new(e).context(format!("Reading file {:?}", rcfile))),
    }?;

    // Extend the argument list with all remaining command line arguments.
    arguments.extend(args.into_iter());
    let opts = Opts::from_iter(&arguments);
    if opts.logging != logging {
        // Try re-initializing the logger.  Ignore errors.
        let _ = env_logger::Builder::from_default_env()
            .filter(None, opts.logging)
            .try_init();
    }
    Ok(opts)
}

#[derive(serde::Serialize, serde::Deserialize)]
pub struct SessionStartResult {
    port: u16,
}

/// Spawn a child process, passing all the same arguments to the child, letting it instantiate a
/// Transport based on the command line arguments, listen on a TCP socket, and run as a daemon
/// process serving network requests.  Success of the child is verified by means of a
/// `SessionStartResult` JSON message sent through the standard output pipe.
fn start_session(run_file_fn: impl FnOnce(u16) -> PathBuf) -> Result<Box<dyn Serialize>> {
    let mut child = Command::new(env::current_exe()?) // Same executable
        .arg("--child") // Add argument to let the new process know it is the daemon child
        .args(args_os().skip(1)) // Propagate all existing arguments: --interface, etc.
        .stdin(Stdio::null()) // Not used by child, disconnect from terminal
        .stdout(Stdio::piped()) // Used for signalling completion of daemon startup
        .stderr(Stdio::inherit()) // May be used for error messages during daemon startup
        .spawn()?;

    match serde_json::from_reader::<&mut ChildStdout, Result<SessionStartResult, String>>(
        child.stdout.as_mut().unwrap(),
    ) {
        Ok(Ok(result)) => {
            // Create a pid file corresponding to the requested TCP port.
            let path = run_file_fn(result.port);
            File::create(path)?.write_all(format!("{}\n", child.id()).as_bytes())?;
            Ok(Box::new(result))
        }
        Ok(Err(e)) => bail!(e),
        Err(e) => bail!("Child process failed to start: {}", e),
    }
}

// This method runs in the daemon child.  It will instantiate SessionHandler to bind to a
// socket, then report the chosen port number to the parent process by means of a serialized
// `SessionStartResult` sent through the stdout anonymous pipe, and finally enter an infnite
// loop, processing connections on that socket
fn session_child(listen_port: Option<u16>, backend_opts: &backend::BackendOpts) -> Result<()> {
    let transport = backend::create(backend_opts)?;
    let mut session = SessionHandler::init(&transport, listen_port)?;
    // Instantiation of Transport backend, and binding to a socket was successful, now go
    // through the process of making this process a daemon, disconnected from the
    // terminal that was used to start it.

    // All configuration files have been processed (relative to current direction), we can now
    // drop the reference to the file system, (in case the admin wants to unmount while this
    // daemon is still running.)
    env::set_current_dir("/")?;

    // Close stderr, which remained open in order to allow any errors from the above code to
    // surface, but needs to be severed in order for the daemon to avoid being killed by SIGHUP
    // if the user closes the terminal window.
    dup2(File::open("/dev/null")?.as_raw_fd(), 2)?;

    // After severing the only connection to the controlling terminal inherited from the parent,
    // we can now establish a new Unix "session" for this process, which will not be
    // "controlled" by any terminal.  This means that this daemon will not be killed by SIGHUP,
    // in case the terminal that was used for running `session start` is later closed.
    setsid()?;

    // Report startup success to parent process.
    serde_json::to_writer::<io::Stdout, Result<SessionStartResult, String>>(
        io::stdout(),
        &Ok(SessionStartResult {
            port: session.get_port(),
        }),
    )?;
    io::stdout().flush()?;

    // Closing the standard output pipe is the signal to the parent process that this child has
    // started up successfully.  We close the pipe indirectly, by replacing file descriptor 1
    // with one pointing to /dev/null.  This will ensure that any subsequent accidentally
    // executed println!() will be a no-op, rather than trigger termination via SIGPIPE.
    dup2(2, 1)?;

    // Indefinitely run command processing loop in this daemon process.
    session.run_loop()
}

#[derive(serde::Serialize, serde::Deserialize)]
pub struct SessionStopResult {}

/// Load .pid file based on given port number, and send SIGTERM to the process identified in the
/// file, to request the daemon gracefully shut down.
fn stop_session(run_file_fn: impl FnOnce(u16) -> PathBuf, port: u16) -> Result<Box<dyn Serialize>> {
    // Read the pid file corresponding to the requested TCP port.
    let path = run_file_fn(port);
    let pid: i32 = FromStr::from_str(&fs::read_to_string(&path)?.trim())?;
    // Send signal to daemon process, asking it to terminate.
    signal::kill(Pid::from_raw(pid), Signal::SIGTERM)?;
    // Wait for daemon process to stop.
    loop {
        std::thread::sleep(Duration::from_millis(100));
        // Send "signal 0", meaning that the kernel performs error checks (among those, checking
        // that the target process exists), without actually sending any signal.
        match signal::kill(Pid::from_raw(pid), None) {
            Ok(()) => (), // Process still running, repeat.
            Err(nix::Error::Sys(nix::errno::Errno::ESRCH)) => {
                // Process could not be found, meaning that it has terminated, as expected.
                fs::remove_file(&path)?;
                return Ok(Box::new(SessionStopResult {}));
            }
            Err(e) => bail!("Unexpected error querying process presence: {}", e),
        }
    }
}

fn main() -> Result<()> {
    let opts = parse_command_line(Opts::from_args(), args_os())?;

    if opts.debug {
        // Start session process in foreground (do not daemonize)
        let transport = backend::create(&opts.backend_opts)?;
        let mut session = SessionHandler::init(&transport, opts.listen_port)?;
        println!("Listening on port {}", session.get_port());
        session.run_loop()?;
        return Ok(());
    }

    if opts.child {
        // This process is a child, which is supposed to stay running as a daemon.
        match session_child(opts.listen_port, &opts.backend_opts) {
            Ok(()) => process::exit(0),
            Err(e) => {
                // Report any error to parent process though stdout pipe.
                serde_json::to_writer::<io::Stdout, Result<SessionStartResult, String>>(
                    io::stdout(),
                    &Err(format!("{}", e).to_string()),
                )?;
                process::exit(1)
            }
        }
    }

    // Locate directory to use for .pid files
    let base_dirs = BaseDirs::new().unwrap();
    let run_user_dir = base_dirs
        .runtime_dir()
        .ok_or(anyhow!("No /run/user directory"))?;
    let run_file_fn = |port: u16| {
        let mut p = PathBuf::from(run_user_dir);
        p.push(format!("opentitansession.{}.pid", port));
        p
    };

    let value = if opts.stop {
        // Send signal to daemon process to stop
        stop_session(run_file_fn, opts.listen_port.unwrap_or(9900))?
    } else {
        // Fork a daemon process
        start_session(run_file_fn)?
    };
    println!("{}", serde_json::to_string_pretty(&value)?);
    Ok(())
}
