use anyhow::Context;
use argh::FromArgs;
use base::RawDescriptor;
use cros_async::Executor;
use hypervisor::ProtectionType;
use crate::virtio::base_features;
use crate::virtio::block::DiskOption;
use crate::virtio::vhost_user_backend::BackendConnection;
use crate::virtio::BlockAsync;
#[derive(FromArgs)]
#[argh(subcommand, name = "block")]
pub struct Options {
    #[argh(option, arg_name = "PATH", hidden_help)]
    socket: Option<String>,
    #[argh(option, arg_name = "PATH")]
    socket_path: Option<String>,
    #[argh(option, arg_name = "FD")]
    fd: Option<RawDescriptor>,
    #[argh(option, arg_name = "PATH<:read-only>")]
    file: String,
}
pub fn start_device(opts: Options) -> anyhow::Result<()> {
    let ex = Executor::new().context("failed to create executor")?;
    let mut fileopts = opts.file.split(':').collect::<Vec<_>>();
    let filename = fileopts.remove(0);
    let disk = DiskOption {
        path: filename.into(),
        read_only: fileopts.contains(&"read-only"),
        sparse: false,
        ..DiskOption::default()
    };
    let block = Box::new(BlockAsync::new(
        base_features(ProtectionType::Unprotected),
        disk.open()?,
        &disk,
        None,
        None,
        None,
    )?);
    let conn =
        BackendConnection::from_opts(opts.socket.as_deref(), opts.socket_path.as_deref(), opts.fd)?;
    conn.run_device(ex, block)
}