// 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.

// Provides the command "set_time" for crosh which provides a way to set the system time before the
// network time is available.

use std::error;
use std::fmt::{self, Display};
use std::io::Read;
use std::process::{self, Stdio};

use dbus::blocking::Connection;
use log::error;
use remain::sorted;
use tlsdate_dbus::client::OrgTorprojectTlsdate;

use crate::dispatcher::{self, Arguments, Command, Dispatcher};
use crate::util::DEFAULT_DBUS_TIMEOUT;

#[sorted]
enum Error {
    Communication,
    DBus,
    InvalidTime,
    NetworkTimeSet,
    UnexpectedResponse(Option<u32>),
    Wrapped(String),
}

impl Display for Error {
    #[remain::check]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Error::*;

        #[sorted]
        match self {
            Communication => write!(f, "Time not set. There was a Communication error."),
            DBus => write!(
                f,
                "Time not set. Unable to communicate with the time service."
            ),
            InvalidTime => write!(f, "Requested time was invalid (too large or too small)"),
            NetworkTimeSet => write!(f, "Time not set. Network time cannot be overridden."),
            UnexpectedResponse(code) => {
                if let Some(value) = code {
                    write!(f, "An unexpected response was received: {}", value)
                } else {
                    write!(f, "An unexpected response was received.")
                }
            }
            Wrapped(err) => write!(f, "{}", err),
        }
    }
}

impl<T: error::Error> From<T> for Error {
    fn from(err: T) -> Self {
        Error::Wrapped(format!("{:?}", err))
    }
}

pub fn register(dispatcher: &mut Dispatcher) {
    dispatcher.register_command(
        Command::new(
            "set_time",
            "<time string>",
            r#"Sets the system time if the the system has been unable to get it from the
  network.  The time may be initialized only once per-boot.

  The <time string> uses the format of the GNU coreutils date command.
  https://www.gnu.org/software/coreutils/manual/html_node/Date-input-formats.html
  https://www.gnu.org/software/coreutils/faq/coreutils-faq.html#The-date-command-is-not-working-right_002e

  Please see the timekeeping documentation for more information in general:
  https://www.chromium.org/chromium-os/chromiumos-design-docs/timekeeping/"#,
        )
        .set_command_callback(Some(execute_set_time)),
    );
}

fn execute_set_time(_cmd: &Command, args: &Arguments) -> Result<(), dispatcher::Error> {
    if args.get_args().is_empty() {
        eprintln!(
            r#"A date/time specification is required.
E.g., set_time 10 February 2012 11:21am
(Remember to set your timezone in Settings first.)"#
        );
        return Err(dispatcher::Error::CommandReturnedError);
    }

    let timestamp = parse_date_string(&args.get_args().join(" ")).map_err(|err| {
        eprintln!("Unable to understand the specified time: {}", err);
        dispatcher::Error::CommandReturnedError
    })?;

    match set_time(timestamp) {
        Ok(()) => {
            println!("Time has been set.");
            Ok(())
        }
        Err(err) => {
            error!("{}", err);
            Err(dispatcher::Error::CommandReturnedError)
        }
    }
}

fn set_time(timestamp: i64) -> Result<(), Error> {
    let connection = Connection::new_system().or(Err(Error::DBus))?;
    let conn_path = connection.with_proxy(
        "org.torproject.tlsdate",
        "/org/torproject/tlsdate",
        DEFAULT_DBUS_TIMEOUT,
    );
    match conn_path.set_time(timestamp).or(Err(Error::DBus))? {
        0 => Ok(()),
        1 => Err(Error::InvalidTime),
        2 => Err(Error::NetworkTimeSet),
        3 => Err(Error::Communication),
        code => Err(Error::UnexpectedResponse(Some(code))),
    }
}

// Rather than reimplementing the human entered date parsing logic from coreutils, just use `date`
// for now.
fn parse_date_string(date: &str) -> Result<i64, Error> {
    let mut child = process::Command::new("date")
        .arg("+%s")
        .arg("-d")
        .arg(date)
        .stdin(Stdio::null())
        .stdout(Stdio::piped())
        .spawn()?;

    let mut string_result = String::new();
    child
        .stdout
        .take()
        .unwrap()
        .read_to_string(&mut string_result)?;
    child.wait()?;
    string_result
        .trim()
        .parse::<i64>()
        .map_err(|err| err.into())
}
