// 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::{format_err, Error},
    argh::FromArgs,
    fidl_fuchsia_fxfs::CryptProxy,
    fuchsia_async as fasync,
    fuchsia_component::server::MissingStartupHandle,
    fuchsia_runtime::HandleType,
    fuchsia_zircon as zx,
    fxfs::{
        filesystem::{mkfs, FxFilesystem, OpenOptions},
        fsck,
        log::*,
        platform::{component::Component, RemoteCrypt},
        serialized_types::LATEST_VERSION,
    },
    remote_block_device::RemoteBlockClient,
    std::sync::Arc,
    storage_device::{block_device::BlockDevice, DeviceHolder},
};

#[derive(FromArgs, PartialEq, Debug)]
/// fxfs
struct TopLevel {
    #[argh(subcommand)]
    nested: SubCommand,

    /// enable additional logging
    #[argh(switch)]
    verbose: bool,
}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum SubCommand {
    Component(ComponentSubCommand),
    Format(FormatSubCommand),
    Fsck(FsckSubCommand),
}

#[derive(FromArgs, PartialEq, Debug)]
/// Format
#[argh(subcommand, name = "mkfs")]
struct FormatSubCommand {
    /// make the default volume encrypted (using supplied crypt service)
    #[argh(switch)]
    encrypted: bool,
}

#[derive(FromArgs, PartialEq, Debug)]
/// Fsck
#[argh(subcommand, name = "fsck")]
struct FsckSubCommand {
    /// check encrypted volumes (with supplied crypt service)
    #[argh(switch)]
    encrypted: bool,
}

#[derive(FromArgs, PartialEq, Debug)]
/// Component
#[argh(subcommand, name = "component")]
struct ComponentSubCommand {}

fn get_crypt_client() -> Result<Arc<RemoteCrypt>, Error> {
    Ok(Arc::new(RemoteCrypt::new(CryptProxy::new(fasync::Channel::from_channel(
        zx::Channel::from(
            fuchsia_runtime::take_startup_handle(fuchsia_runtime::HandleInfo::new(
                HandleType::User0,
                2,
            ))
            .ok_or(format_err!("Missing crypt service"))?,
        ),
    )?))))
}

// The number of threads chosen here must exceed the number of concurrent system calls to paged VMOs
// that we allow since otherwise deadlocks are possible.  Search for CONCURRENT_SYSCALLS.
#[fasync::run(10)]
async fn main() -> Result<(), Error> {
    diagnostics_log::init!();

    #[cfg(feature = "tracing")]
    fuchsia_trace_provider::trace_provider_create_with_fdio();

    info!(version = %LATEST_VERSION, "Started");

    let args: TopLevel = argh::from_env();

    if let TopLevel { nested: SubCommand::Component(_), .. } = args {
        return Component::new()
            .run(
                fuchsia_runtime::take_startup_handle(HandleType::DirectoryRequest.into())
                    .ok_or(MissingStartupHandle)?
                    .into(),
                fuchsia_runtime::take_startup_handle(HandleType::Lifecycle.into())
                    .map(|h| h.into()),
            )
            .await;
    }

    let client = RemoteBlockClient::new(zx::Channel::from(
        fuchsia_runtime::take_startup_handle(fuchsia_runtime::HandleInfo::new(
            HandleType::User0,
            1,
        ))
        .ok_or(format_err!("Missing device handle"))?,
    ))
    .await?;

    match args {
        TopLevel { nested: SubCommand::Format(FormatSubCommand { encrypted }), .. } => {
            mkfs(
                DeviceHolder::new(BlockDevice::new(Box::new(client), false).await?),
                if encrypted { Some(get_crypt_client()?) } else { None },
            )
            .await?;
            Ok(())
        }
        TopLevel { nested: SubCommand::Fsck(FsckSubCommand { encrypted }), verbose } => {
            let fs = FxFilesystem::open_with_options(
                DeviceHolder::new(BlockDevice::new(Box::new(client), true).await?),
                OpenOptions { read_only: true, trace: verbose, ..Default::default() },
            )
            .await?;
            let mut options = fsck::default_options();
            options.verbose = verbose;
            fsck::fsck_with_options(
                &fs,
                if encrypted { Some(get_crypt_client()?) } else { None },
                options,
            )
            .await
        }
        TopLevel { nested: SubCommand::Component(_), .. } => unreachable!(),
    }
}
