// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    argh::FromArgs,
    fidl_fuchsia_update_installer_ext::Initiator as ExtInitiator,
    fuchsia_url::pkg_url::PkgUrl,
    std::time::{Duration, SystemTime},
};

#[derive(Debug, Eq, FromArgs, PartialEq)]
/// Arguments for the system updater.
pub struct Args {
    /// what started this update: manual or automatic
    #[argh(option, default = "Initiator::Automatic")]
    pub initiator: Initiator,

    /// current OS version
    #[argh(option, default = "String::from(\"\")")]
    pub source: String,

    /// target OS version
    #[argh(option, default = "String::from(\"\")")]
    pub target: String,

    /// update package url
    #[argh(option, default = "\"fuchsia-pkg://fuchsia.com/update\".parse().unwrap()")]
    pub update: PkgUrl,

    /// if true, reboot the system after successful OTA
    #[argh(option, default = "true")]
    pub reboot: bool,

    /// if true, don't write the recovery image
    #[argh(option, default = "false")]
    pub skip_recovery: bool,

    /// start time of update attempt, as unix nanosecond timestamp
    #[argh(option, from_str_fn(parse_wall_time))]
    pub start: Option<SystemTime>,

    /// if true, the system updater will install a single update and exit
    #[argh(option, default = "false")]
    pub oneshot: bool,
}

fn parse_wall_time(value: &str) -> Result<SystemTime, String> {
    let since_unix_epoch =
        Duration::from_nanos(value.parse().map_err(|e: std::num::ParseIntError| e.to_string())?);

    Ok(SystemTime::UNIX_EPOCH + since_unix_epoch)
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Initiator {
    Automatic,
    Manual,
}

impl From<Initiator> for ExtInitiator {
    fn from(args_initiator: Initiator) -> Self {
        match args_initiator {
            Initiator::Manual => ExtInitiator::User,
            Initiator::Automatic => ExtInitiator::Service,
        }
    }
}

impl From<ExtInitiator> for Initiator {
    fn from(ext_initiator: ExtInitiator) -> Self {
        match ext_initiator {
            ExtInitiator::User => Initiator::Manual,
            ExtInitiator::Service => Initiator::Automatic,
        }
    }
}

impl std::str::FromStr for Initiator {
    type Err = anyhow::Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "automatic" => Ok(Initiator::Automatic),
            "manual" => Ok(Initiator::Manual),
            not_supported => Err(anyhow::anyhow!("initiator not supported: {:?}", not_supported)),
        }
    }
}

#[cfg(test)]
mod tests {
    use {super::*, matches::assert_matches};

    #[test]
    fn test_initiator() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--initiator", "manual"]),
            Ok(Args { initiator: Initiator::Manual, .. })
        );
    }

    #[test]
    fn test_unknown_initiator() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--initiator", "P Sherman"]),
            Err(_)
        );
    }

    #[test]
    fn test_start() {
        use chrono::prelude::*;

        const NANOS_IN_1970: u64 = 365 * 24 * 60 * 60 * 1_000_000_000;
        let nanos_in_1970 = NANOS_IN_1970.to_string();

        let args = Args::from_args(&["system-updater"], &["--start", &nanos_in_1970]).unwrap();
        assert_eq!(args.start, Some(Utc.ymd(1971, 1, 1).and_hms(0, 0, 0).into()));
    }

    #[test]
    fn test_source() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--source", "Wallaby Way"]),
            Ok(Args {
                source: source_version,
                ..
            }) if source_version=="Wallaby Way"
        );
    }

    #[test]
    fn test_target() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--target", "Sydney"]),
            Ok(Args {
                target: target_version,
                ..
            }) if target_version=="Sydney"
        );
    }

    #[test]
    fn test_update() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--update", "fuchsia-pkg://fuchsia.com/foo"]),
            Ok(Args {
                update: update_pkg_url,
                ..
            }) if update_pkg_url.to_string() == "fuchsia-pkg://fuchsia.com/foo"
        );
    }

    #[test]
    fn test_reboot() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--reboot", "false"]),
            Ok(Args { reboot: false, .. })
        );
    }

    #[test]
    fn test_skip_recovery() {
        assert_matches!(
            Args::from_args(&["system-updater"], &["--skip-recovery", "true"]),
            Ok(Args { skip_recovery: true, .. })
        );
    }

    #[test]
    fn test_defaults() {
        assert_matches!(
            Args::from_args(&["system-updater"], &[]),
            Ok(Args {
                initiator: Initiator::Automatic,
                source: source_version,
                target: target_version,
                update: update_pkg_url,
                reboot: true,
                skip_recovery: false,
                ..
            }) if source_version == "" &&
                  target_version == "" &&
                  update_pkg_url.to_string() == "fuchsia-pkg://fuchsia.com/update"
        );
    }
}
