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

#![feature(async_await, await_macro, futures_api)]
#![deny(warnings)]

use failure::{Error, ResultExt};
use files_async;
use fuchsia_app::client::Launcher;
use fuchsia_async as fasync;
use fidl_fuchsia_pkg::{PackageCacheMarker, PackageResolverMarker, UpdatePolicy};
use fidl_fuchsia_pkg_ext::BlobId;
use fuchsia_zircon as zx;
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(name = "pkgctl")]
struct Options {
    #[structopt(
        long = "pkg-resolver-uri",
        help = "Package URI of the package resolver",
        default_value = "fuchsia-pkg://fuchsia.com/pkg_resolver#meta/pkg_resolver.cmx"
    )]
    pkg_resolver_uri: String,

    #[structopt(
        long = "pkg-cache-uri",
        help = "Package URI of the package cache",
        default_value = "fuchsia-pkg://fuchsia.com/pkg_cache#meta/pkg_cache.cmx"
    )]
    pkg_cache_uri: String,

    #[structopt(subcommand)]
    cmd: Command,
}

#[derive(StructOpt)]
enum Command {
    #[structopt(name = "resolve", about = "resolve a package")]
    Resolve {
        #[structopt(help = "URI of package to cache")]
        pkg_uri: String,

        #[structopt(help = "Package selectors")]
        selectors: Vec<String>,
    },
    #[structopt(name = "open", about = "open a package by merkle root")]
    Open {
        #[structopt(help = "Merkle root of package's meta.far to cache")]
        meta_far_blob_id: BlobId,

        #[structopt(help = "Package selectors")]
        selectors: Vec<String>,
    },
}

fn main() -> Result<(), Error> {
    let mut executor = fasync::Executor::new().context("Error creating executor")?;

    let Options {
        pkg_resolver_uri,
        pkg_cache_uri,
        cmd,
    } = Options::from_args();

    // Launch the server and connect to the resolver service.
    let launcher = Launcher::new().context("Failed to open launcher service")?;

    let fut = async {
        match cmd {
            Command::Resolve { pkg_uri, selectors } => {
                let app = launcher
                    .launch(pkg_resolver_uri, None)
                    .context("Failed to launch resolver service")?;
                let resolver = app
                    .connect_to_service(PackageResolverMarker)
                    .context("Failed to connect to resolver service")?;
                println!("resolving {} with the selectors {:?}", pkg_uri, selectors);

                let (dir, dir_server_end) = fidl::endpoints::create_proxy()?;

                let res = await!(resolver.resolve(
                    &pkg_uri,
                    &mut selectors.iter().map(|s| s.as_str()),
                    &mut UpdatePolicy {
                        fetch_if_absent: true,
                        allow_old_versions: true,
                    },
                    dir_server_end,
                ))?;
                zx::Status::ok(res)?;

                let entries = await!(files_async::readdir_recursive(dir))?;
                println!("package contents:");
                for entry in entries {
                    println!("/{:?}", entry);
                }

                Ok(())
            }
            Command::Open {
                meta_far_blob_id,
                selectors,
            } => {
                let app = launcher
                    .launch(pkg_cache_uri, None)
                    .context("Failed to launch cache service")?;
                let cache = app
                    .connect_to_service(PackageCacheMarker)
                    .context("Failed to connect to cache service")?;
                println!(
                    "opening {} with the selectors {:?}",
                    meta_far_blob_id, selectors
                );

                let (dir, dir_server_end) = fidl::endpoints::create_proxy()?;

                let res = await!(cache.open(
                    &mut meta_far_blob_id.into(),
                    &mut selectors.iter().map(|s| s.as_str()),
                    dir_server_end,
                ))?;
                zx::Status::ok(res)?;

                let entries = await!(files_async::readdir_recursive(dir))?;
                println!("package contents:");
                for entry in entries {
                    println!("/{:?}", entry);
                }

                Ok(())
            }
        }
    };

    executor.run_singlethreaded(fut)
}
