// Copyright 2021 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 anyhow::{Context, Error};
use argh::FromArgs;
use fidl_fuchsia_tpm_cr50::{
    Cr50Marker, Cr50Proxy, Cr50Rc, Cr50Status, PhysicalPresenceEvent,
    PhysicalPresenceNotifierEvent, PhysicalPresenceNotifierProxy, PhysicalPresenceState, WpState,
};
use fuchsia_zircon as zx;
use futures::TryStreamExt;

#[derive(FromArgs, PartialEq, Debug)]
/// A tool to interact with the Cr50 TPM.
struct Args {
    #[argh(subcommand)]
    cmd: SubCommand,
}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum SubCommand {
    Ccd(CcdSubCommand),
    Wp(WpCommand),
}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "ccd")]
/// interact with case-closed debugging features.
struct CcdSubCommand {
    #[argh(subcommand)]
    cmd: CcdCommand,
}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
/// command to use.
enum CcdCommand {
    GetInfo(GetInfo),
    Lock(CcdLock),
    Unlock(CcdUnlock),
    Open(CcdOpen),
}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "get-info")]
/// get info about CCD.
struct GetInfo {}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "lock")]
/// lock CCD.
struct CcdLock {}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "open")]
/// open CCD.
struct CcdOpen {}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "unlock")]
/// unlock CCD.
struct CcdUnlock {}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "wp")]
/// get the current write protect state.
struct WpCommand {}

#[fuchsia::main]
async fn main() {
    let args: Args = argh::from_env();
    run_cmd(args).await.unwrap_or_else(|e| {
        println!("Error while running command: {:?}", e);
    });
}

async fn handle_pp(client: PhysicalPresenceNotifierProxy) -> Result<(), Error> {
    let mut started = false;
    while let Some(event) =
        client.take_event_stream().try_next().await.context("Getting next event")?
    {
        match event {
            PhysicalPresenceNotifierEvent::OnChange { event } => match event {
                PhysicalPresenceEvent::State(PhysicalPresenceState::Done) => {
                    println!("Success!");
                    return Ok(());
                }
                PhysicalPresenceEvent::State(PhysicalPresenceState::Closed) => {
                    if started {
                        println!("Timed out, try again.");
                    } else {
                        println!("Done");
                    }
                    return Ok(());
                }
                PhysicalPresenceEvent::State(PhysicalPresenceState::AwaitingPress) => {
                    println!("Press the power button NOW!")
                }
                PhysicalPresenceEvent::State(PhysicalPresenceState::BetweenPresses) => {
                    println!("Waiting - another press will be needed soon...")
                }
                PhysicalPresenceEvent::Err(_) => {
                    println!("Internal error while polling for physical presence, try again?")
                }
                _ => unimplemented!(),
            },
        }
        started = true;
    }

    Ok(())
}

async fn run_ccd(proxy: Cr50Proxy, cmd: CcdCommand) -> Result<(), Error> {
    match cmd {
        CcdCommand::GetInfo(_) => {
            let (rc, info) = proxy
                .ccd_get_info()
                .await
                .context("Getting info (Sending FIDL request)")?
                .map_err(zx::Status::from_raw)
                .context("Getting info (Server-side failure)")?;
            if let Some(info) = info {
                println!("CCD state: {:?}", info.state);
                println!("CCD force disabled: {}", info.force_disabled);
                println!("CCD flags: {:?}", info.flags);
                println!("CCD indicator: {:?}", info.indicator);
                println!("Capabilities:");
                println!("{:^32} {:^16} {:^16}", "CAPABILITY", "CURRENT STATE", "(DEFAULT STATE)");
                for cap in info.capabilities.iter() {
                    print!(
                        "{:^32} {:^16}",
                        format!("{:?}", cap.capability),
                        format!("{:?}", cap.current_state)
                    );
                    if cap.current_state != cap.default_state {
                        println!(" {:^16}", format!("({:?})", cap.default_state));
                    } else {
                        println!();
                    }
                }
            } else {
                println!("Error: {:?}", rc);
            }
        }
        CcdCommand::Lock(_) => {
            let rc = proxy
                .ccd_lock()
                .await
                .context("Locking CCD (Sending FIDL request)")?
                .map_err(zx::Status::from_raw)
                .context("Locking CCD (Server-side failure)")?;
            if rc == Cr50Rc::Cr50(Cr50Status::Success) {
                println!("CCD locked");
            } else {
                println!("Failed to lock CCD: {:?}", rc);
            }
        }
        CcdCommand::Open(_) => {
            let (rc, client) = proxy
                .ccd_open(None)
                .await
                .context("Opening CCD (Sending FIDL request)")?
                .map_err(zx::Status::from_raw)
                .context("Opening CCD (Server-side failure)")?;

            match rc {
                Cr50Rc::Cr50(Cr50Status::Success) | Cr50Rc::Cr50(Cr50Status::InProgress) => {
                    handle_pp(client.unwrap().into_proxy().context("Making proxy")?)
                        .await
                        .context("Handling PP")?;
                }
                err => println!("Failed to open: {:?}", err),
            }
        }
        CcdCommand::Unlock(_) => {
            let (rc, client) = proxy
                .ccd_unlock(None)
                .await
                .context("Unlocking CCD (Sending FIDL request)")?
                .map_err(zx::Status::from_raw)
                .context("Unlocking CCD (Server-side failure)")?;

            match rc {
                Cr50Rc::Cr50(Cr50Status::Success) | Cr50Rc::Cr50(Cr50Status::InProgress) => {
                    handle_pp(client.unwrap().into_proxy().context("Making proxy")?)
                        .await
                        .context("Handling PP")?
                }
                err => println!("Failed to unlock: {:?}", err),
            }
        }
    };

    Ok(())
}

async fn run_cmd(args: Args) -> Result<(), Error> {
    let proxy = fuchsia_component::client::connect_to_protocol::<Cr50Marker>()
        .context("Connecting to firmware parameter service")?;
    match args.cmd {
        SubCommand::Ccd(CcdSubCommand { cmd }) => run_ccd(proxy, cmd).await?,
        SubCommand::Wp(_) => {
            let (rc, state) = proxy
                .wp_get_state()
                .await
                .context("Getting state")?
                .map_err(zx::Status::from_raw)
                .context("Getting state")?;
            if rc != Cr50Rc::Cr50(Cr50Status::Success) {
                println!("Error: {:?}", rc);
            } else {
                print!("WP state: ");
                if state.contains(WpState::FORCE) {
                    print!("force ");
                }
                if state.contains(WpState::ENABLE) {
                    println!("enabled");
                } else {
                    println!("disabled");
                }
                print!("At boot:  ");
                if state.contains(WpState::AT_BOOT_SET) {
                    print!("force ");
                    if state.contains(WpState::AT_BOOT_ENABLE) {
                        println!("enable");
                    } else {
                        println!("disable");
                    }
                } else {
                    println!("follow_batt_pres");
                }
            }
        }
    };

    Ok(())
}
