// Copyright 2022 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 {
    crate::resolver_service::Resolver,
    anyhow::{anyhow, Context as _, Error},
    async_lock::RwLock as AsyncRwLock,
    eager_package_config::pkg_resolver::{EagerPackageConfig, EagerPackageConfigs},
    fidl_fuchsia_io as fio,
    fidl_fuchsia_pkg::{self as fpkg, CupRequest, CupRequestStream, GetInfoError, WriteError},
    fidl_fuchsia_pkg_ext::{cache, BlobInfo, CupData, CupMissingField, ResolutionContext},
    fidl_fuchsia_pkg_internal::{PersistentEagerPackage, PersistentEagerPackages},
    fuchsia_pkg::PackageDirectory,
    fuchsia_syslog::fx_log_err,
    fuchsia_url::{AbsolutePackageUrl, Hash, PinnedAbsolutePackageUrl, UnpinnedAbsolutePackageUrl},
    fuchsia_zircon as zx,
    futures::prelude::*,
    omaha_client::{
        cup_ecdsa::{CupVerificationError, Cupv2Verifier, PublicKeys, StandardCupv2Handler},
        protocol::response::Response,
    },
    p256::ecdsa::{signature::Signature, DerSignature},
    std::{collections::BTreeMap, convert::TryInto, sync::Arc},
};

const EAGER_PACKAGE_PERSISTENT_FIDL_NAME: &str = "eager_packages.pf";

#[derive(Clone, Debug)]
struct EagerPackage {
    #[allow(dead_code)]
    executable: bool,
    package_directory: Option<PackageDirectory>,
    cup: Option<CupData>,
    public_keys: PublicKeys,
}

#[derive(Debug)]
pub struct EagerPackageManager<T: Resolver> {
    packages: BTreeMap<UnpinnedAbsolutePackageUrl, EagerPackage>,
    package_resolver: T,
    data_proxy: Option<fio::DirectoryProxy>,
}

async fn verify_cup_signature(
    cup_handler: &StandardCupv2Handler,
    cup: &CupData,
) -> Result<(), ParseCupResponseError> {
    let der_signature = DerSignature::from_bytes(&cup.signature)?;
    cup_handler
        .verify_response_with_signature(
            &der_signature,
            &cup.request,
            &cup.response,
            cup.key_id,
            &cup.nonce.into(),
        )
        .map_err(ParseCupResponseError::VerificationError)
}

impl<T: Resolver> EagerPackageManager<T> {
    pub async fn from_namespace(
        package_resolver: T,
        pkg_cache: cache::Client,
        data_proxy: Option<fio::DirectoryProxy>,
    ) -> Result<Self, Error> {
        let config =
            EagerPackageConfigs::from_namespace().await.context("loading eager package config")?;
        Ok(Self::from_config(config, package_resolver, pkg_cache, data_proxy).await)
    }

    async fn from_config(
        config: EagerPackageConfigs,
        package_resolver: T,
        pkg_cache: cache::Client,
        data_proxy: Option<fio::DirectoryProxy>,
    ) -> Self {
        let mut packages = config
            .packages
            .into_iter()
            .map(|EagerPackageConfig { url, executable, public_keys }| {
                (url, EagerPackage { executable, package_directory: None, cup: None, public_keys })
            })
            .collect();

        if let Some(ref data_proxy) = data_proxy {
            if let Err(e) =
                Self::load_persistent_eager_packages(&mut packages, pkg_cache, &data_proxy).await
            {
                fx_log_err!("failed to load persistent eager packages: {:#}", anyhow!(e));
            }
        }

        Self { packages, package_resolver, data_proxy }
    }

    async fn load_persistent_eager_packages(
        packages: &mut BTreeMap<UnpinnedAbsolutePackageUrl, EagerPackage>,
        pkg_cache: cache::Client,
        data_proxy: &fio::DirectoryProxy,
    ) -> Result<(), Error> {
        let file_proxy = match fuchsia_fs::directory::open_file(
            data_proxy,
            EAGER_PACKAGE_PERSISTENT_FIDL_NAME,
            fio::OpenFlags::RIGHT_READABLE,
        )
        .await
        {
            Ok(proxy) => proxy,
            Err(fuchsia_fs::node::OpenError::OpenError(s)) if s == zx::Status::NOT_FOUND => {
                return Ok(())
            }
            Err(e) => Err(e).context("while opening eager_packages.pf")?,
        };

        let persistent_packages =
            fuchsia_fs::read_file_fidl::<PersistentEagerPackages>(&file_proxy)
                .await
                .context("while reading eager_packages.pf")?;
        for PersistentEagerPackage { url, cup, .. } in persistent_packages
            .packages
            .ok_or_else(|| anyhow!("PersistentEagerPackages does not contain `packages` field"))?
        {
            async {
                let url = url.ok_or_else(|| {
                    anyhow!("PersistentEagerPackage does not contain `url` field")
                })?;
                let cup: CupData = cup
                    .ok_or_else(|| anyhow!("PersistentEagerPackage does not contain `cup` field"))?
                    .try_into()?;
                let response = parse_omaha_response_from_cup(&cup)
                    .with_context(|| format!("while parsing omaha response {:?}", cup.response))?;
                let pinned_url = response
                    .apps
                    .iter()
                    .find_map(|app| {
                        app.update_check
                            .as_ref()
                            .and_then(|uc| uc.get_all_full_urls().find(|u| u.starts_with(&url.url)))
                    })
                    .ok_or_else(|| {
                        anyhow!("could not find pinned url in CUP omaha response for {}", url.url)
                    })?;
                let pinned_url: PinnedAbsolutePackageUrl =
                    pinned_url.parse().with_context(|| format!("while parsing {}", url.url))?;
                let unpinned_url = pinned_url.as_unpinned();
                let package = packages
                    .get_mut(&unpinned_url)
                    .ok_or_else(|| anyhow!("unknown pkg url: {}", url.url))?;

                let cup_handler = StandardCupv2Handler::new(&package.public_keys);

                verify_cup_signature(&cup_handler, &cup)
                    .await
                    .map_err(|e| anyhow!("could not verify cup signature {:?}", e))?;

                package.cup = Some(cup);

                let pkg_dir =
                    Self::resolve_pinned_from_cache(&pkg_cache, pinned_url).await.with_context(
                        || format!("while resolving eager package {} from cache", url.url),
                    )?;
                package.package_directory = Some(pkg_dir);
                Ok(())
            }
            .await
            .unwrap_or_else(|e: Error| {
                fx_log_err!("failed to load persistent eager package: {:#}", anyhow!(e))
            })
        }
        Ok(())
    }

    // Returns eager package directory.
    // Returns Ok(None) if that's not an eager package, or the package is pinned.
    pub fn get_package_dir(
        &self,
        url: &AbsolutePackageUrl,
    ) -> Result<Option<PackageDirectory>, Error> {
        let url = match url {
            AbsolutePackageUrl::Unpinned(unpinned) => unpinned,
            AbsolutePackageUrl::Pinned(_) => return Ok(None),
        };
        if let Some(eager_package) = self.packages.get(url) {
            if eager_package.package_directory.is_some() {
                Ok(eager_package.package_directory.clone())
            } else {
                Err(anyhow!("eager package dir not found for {}", url))
            }
        } else {
            Ok(None)
        }
    }

    async fn resolve_pinned(
        package_resolver: &T,
        url: PinnedAbsolutePackageUrl,
    ) -> Result<(PackageDirectory, ResolutionContext), ResolvePinnedError> {
        let expected_hash = url.hash();
        let (pkg_dir, resolution_context) = package_resolver.resolve(url.into(), None).await?;
        let hash = pkg_dir.merkle_root().await?;
        if hash != expected_hash {
            return Err(ResolvePinnedError::HashMismatch(hash));
        }
        Ok((pkg_dir, resolution_context))
    }

    async fn resolve_pinned_from_cache(
        pkg_cache: &cache::Client,
        url: PinnedAbsolutePackageUrl,
    ) -> Result<PackageDirectory, Error> {
        let mut get = pkg_cache
            .get(BlobInfo { blob_id: url.hash().into(), length: 0 })
            .context("pkg cache get")?;
        if let Some(_needed_blob) = get.open_meta_blob().await.context("open_meta_blob")? {
            return Err(anyhow!("meta blob missing"));
        }
        let missing_blobs = get.get_missing_blobs().await.context("get_missing_blobs")?;
        if !missing_blobs.is_empty() {
            return Err(anyhow!("at least one blob missing: {:?}", missing_blobs));
        }
        Ok(get.finish().await.context("finish")?)
    }

    async fn persist(
        &self,
        packages: &BTreeMap<UnpinnedAbsolutePackageUrl, EagerPackage>,
    ) -> Result<(), PersistError> {
        let data_proxy = self.data_proxy.as_ref().ok_or(PersistError::DataProxyNotAvailable)?;

        let packages = packages
            .iter()
            .map(|(url, package)| PersistentEagerPackage {
                url: Some(fpkg::PackageUrl { url: url.to_string() }),
                cup: package.cup.clone().map(Into::into),
                ..PersistentEagerPackage::EMPTY
            })
            .collect();
        let mut packages =
            PersistentEagerPackages { packages: Some(packages), ..PersistentEagerPackages::EMPTY };

        let temp_path = &format!("{EAGER_PACKAGE_PERSISTENT_FIDL_NAME}.new");
        crate::util::do_with_atomic_file(
            &data_proxy,
            temp_path,
            EAGER_PACKAGE_PERSISTENT_FIDL_NAME,
            |proxy| async move {
                fuchsia_fs::write_file_fidl(&proxy, &mut packages)
                    .await
                    .with_context(|| format!("writing file: {}", temp_path))
            },
        )
        .await
        .map_err(PersistError::AtomicWrite)
    }

    async fn cup_write(
        &mut self,
        url: &fpkg::PackageUrl,
        cup: fpkg::CupData,
    ) -> Result<(), CupWriteError> {
        let cup_data: CupData = cup.try_into()?;
        let response = parse_omaha_response_from_cup(&cup_data)?;
        // The full URL must appear in the omaha response.
        let _app = response
            .apps
            .iter()
            .find(|app| {
                app.update_check
                    .as_ref()
                    .and_then(|uc| uc.get_all_full_urls().find(|u| u == &url.url))
                    .is_some()
            })
            .ok_or(CupWriteError::CupResponseURLNotFound)?;

        let pinned_url: PinnedAbsolutePackageUrl = url.url.parse()?;
        let mut packages = self.packages.clone();
        // Make sure the url is an eager package before trying to resolve it.
        let package = packages
            .get_mut(pinned_url.as_unpinned())
            .ok_or_else(|| CupWriteError::UnknownURL(pinned_url.as_unpinned().clone()))?;
        let (pkg_dir, _resolution_context) =
            Self::resolve_pinned(&self.package_resolver, pinned_url).await?;
        package.package_directory = Some(pkg_dir);

        let cup_handler = StandardCupv2Handler::new(&package.public_keys);
        verify_cup_signature(&cup_handler, &cup_data).await?;

        package.cup = Some(cup_data);

        self.persist(&packages).await?;
        // Only update self.packages if persist succeed, to prevent rollback after reboot.
        self.packages = packages;
        Ok(())
    }

    async fn cup_get_info(
        &self,
        url: &fpkg::PackageUrl,
    ) -> Result<(String, String), CupGetInfoError> {
        let pkg_url = UnpinnedAbsolutePackageUrl::parse(&url.url)?;
        let package =
            self.packages.get(&pkg_url).ok_or_else(|| CupGetInfoError::UnknownURL(pkg_url))?;
        let cup = package.cup.as_ref().ok_or(CupGetInfoError::CupDataNotAvailable)?;
        let response = parse_omaha_response_from_cup(&cup)?;
        let app = response
            .apps
            .iter()
            .find(|app| {
                app.update_check
                    .as_ref()
                    .and_then(|uc| uc.get_all_full_urls().find(|u| u.starts_with(&url.url)))
                    .is_some()
            })
            .ok_or(CupGetInfoError::CupResponseURLNotFound)?;
        let version = app.get_manifest_version().ok_or(CupGetInfoError::CupDataMissingVersion)?;
        let channel = app.cohort.name.clone().ok_or(CupGetInfoError::CupDataMissingChannel)?;
        Ok((version, channel))
    }
}

fn parse_omaha_response_from_cup(cup: &CupData) -> Result<Response, ParseCupResponseError> {
    Ok(omaha_client::protocol::response::parse_json_response(&cup.response)?)
}

#[derive(Debug, thiserror::Error)]
enum ParseCupResponseError {
    #[error("CUP data signature is invalid")]
    CupDataInvalidSignature(#[from] p256::ecdsa::Error),
    #[error("while validating CUP response")]
    VerificationError(#[from] CupVerificationError),
    #[error("while parsing JSON")]
    ParseJSON(#[from] serde_json::Error),
}

#[derive(Debug, thiserror::Error)]
enum ResolvePinnedError {
    #[error("while resolving package")]
    Resolve(#[from] fidl_fuchsia_pkg_ext::ResolveError),
    #[error("while reading package hash")]
    ReadHash(#[from] fuchsia_pkg::ReadHashError),
    #[error("resolved package hash '{0}' does not match")]
    HashMismatch(Hash),
}

#[derive(Debug, thiserror::Error)]
enum PersistError {
    #[error("directory proxy to /data is not available")]
    DataProxyNotAvailable,
    #[error("while opening temp file")]
    Open(#[from] fuchsia_fs::node::OpenError),
    #[error("while writing persistent fidl")]
    AtomicWrite(#[source] anyhow::Error),
}

#[derive(Debug, thiserror::Error)]
enum CupWriteError {
    #[error("CUP data does not include a field")]
    Missing(#[from] CupMissingField),
    #[error("while parsing package URL")]
    ParseURL(#[from] fuchsia_url::errors::ParseError),
    #[error("URL is not a known eager package: {0}")]
    UnknownURL(UnpinnedAbsolutePackageUrl),
    #[error("while resolving package")]
    ResolvePinned(#[from] ResolvePinnedError),
    #[error("while parsing CUP omaha response")]
    ParseCupResponse(#[from] ParseCupResponseError),
    #[error("URL not found in CUP omaha response")]
    CupResponseURLNotFound,
    #[error("while persisting CUP data")]
    Persist(#[from] PersistError),
}

impl From<&CupWriteError> for WriteError {
    fn from(err: &CupWriteError) -> WriteError {
        match err {
            CupWriteError::ParseURL(_) => WriteError::UnknownUrl,
            CupWriteError::UnknownURL(_) => WriteError::UnknownUrl,
            CupWriteError::ResolvePinned(_) => WriteError::Download,
            CupWriteError::Missing(_) => WriteError::Verification,
            CupWriteError::ParseCupResponse(_) => WriteError::Verification,
            CupWriteError::CupResponseURLNotFound => WriteError::Verification,
            CupWriteError::Persist(_) => WriteError::Storage,
        }
    }
}

#[derive(Debug, thiserror::Error)]
enum CupGetInfoError {
    #[error("while parsing package URL")]
    ParseURL(#[from] fuchsia_url::errors::ParseError),
    #[error("URL is not a known eager package: {0}")]
    UnknownURL(UnpinnedAbsolutePackageUrl),
    #[error("CUP data is not available for this eager package")]
    CupDataNotAvailable,
    #[error("URL not found in CUP omaha response")]
    CupResponseURLNotFound,
    #[error("CUP data does not include version")]
    CupDataMissingVersion,
    #[error("CUP data does not include channel")]
    CupDataMissingChannel,
    #[error("while parsing CUP omaha response")]
    ParseCupResponse(#[from] ParseCupResponseError),
}

impl From<&CupGetInfoError> for GetInfoError {
    fn from(err: &CupGetInfoError) -> GetInfoError {
        match err {
            CupGetInfoError::ParseURL(_) => GetInfoError::UnknownUrl,
            CupGetInfoError::UnknownURL(_) => GetInfoError::UnknownUrl,
            CupGetInfoError::CupDataNotAvailable => GetInfoError::NotAvailable,
            CupGetInfoError::CupResponseURLNotFound => GetInfoError::Verification,
            CupGetInfoError::CupDataMissingVersion => GetInfoError::Verification,
            CupGetInfoError::CupDataMissingChannel => GetInfoError::Verification,
            CupGetInfoError::ParseCupResponse(_) => GetInfoError::Verification,
        }
    }
}

pub async fn run_cup_service<T: Resolver>(
    manager: Arc<Option<AsyncRwLock<EagerPackageManager<T>>>>,
    mut stream: CupRequestStream,
) -> Result<(), Error> {
    while let Some(event) = stream.try_next().await? {
        match event {
            CupRequest::Write { url, cup, responder } => {
                let mut response = match manager.as_ref() {
                    Some(manager) => {
                        manager.write().await.cup_write(&url, cup).await.map_err(|e| {
                            let write_error = (&e).into();
                            fx_log_err!("cup_write failed for url '{}': {:#}", url.url, anyhow!(e));
                            write_error
                        })
                    }
                    None => Err(WriteError::Storage),
                };
                responder.send(&mut response)?;
            }
            CupRequest::GetInfo { url, responder } => {
                let mut response = match manager.as_ref() {
                    Some(manager) => manager.read().await.cup_get_info(&url).await.map_err(|e| {
                        let get_info_error = (&e).into();
                        fx_log_err!("cup_get_info failed for url '{}': {:#}", url.url, anyhow!(e));
                        get_info_error
                    }),
                    None => Err(GetInfoError::NotAvailable),
                };
                responder.send(&mut response)?;
            }
        }
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        crate::resolver_service::MockResolver,
        assert_matches::assert_matches,
        fidl_fuchsia_pkg::{
            BlobInfoIteratorRequest, NeededBlobsRequest, PackageCacheMarker, PackageCacheRequest,
            PackageCacheRequestStream,
        },
        fidl_fuchsia_pkg_ext as pkg, fuchsia_async as fasync, fuchsia_zircon as zx,
        omaha_client::{
            cup_ecdsa::{
                test_support::{
                    make_default_public_key_for_test, make_default_public_key_id_for_test,
                    make_default_public_keys_for_test, make_expected_signature_for_test,
                    make_keys_for_test, make_public_keys_for_test,
                    make_standard_intermediate_for_test, RAW_PUBLIC_KEY_FOR_TEST,
                },
                Cupv2RequestHandler, PublicKeyAndId, PublicKeyId, PublicKeys,
            },
            protocol::request::Request,
        },
    };

    const TEST_URL: &str = "fuchsia-pkg://example.com/package";
    const TEST_HASH: &str = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
    const TEST_PINNED_URL: &str = "fuchsia-pkg://example.com/package?hash=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";

    fn get_test_package_resolver() -> MockResolver {
        let pkg_dir = PackageDirectory::open_from_namespace().unwrap();
        MockResolver::new(move |_url| {
            let pkg_dir = pkg_dir.clone();
            async move { Ok((pkg_dir, pkg::ResolutionContext::new(vec![]))) }
        })
    }

    fn get_mock_pkg_cache() -> (cache::Client, PackageCacheRequestStream) {
        let (proxy, stream) =
            fidl::endpoints::create_proxy_and_stream::<PackageCacheMarker>().unwrap();
        (cache::Client::from_proxy(proxy), stream)
    }

    async fn handle_pkg_cache(mut stream: PackageCacheRequestStream) {
        while let Some(request) = stream.try_next().await.unwrap() {
            match request {
                PackageCacheRequest::Get { meta_far_blob, needed_blobs, dir: _, responder } => {
                    if meta_far_blob.blob_id.merkle_root
                        != TEST_HASH.parse::<Hash>().unwrap().as_bytes()
                    {
                        responder.send(&mut Err(zx::Status::NOT_FOUND.into_raw())).unwrap();
                        continue;
                    }
                    let mut needed_blobs = needed_blobs.into_stream().unwrap();
                    while let Some(request) = needed_blobs.try_next().await.unwrap() {
                        match request {
                            NeededBlobsRequest::OpenMetaBlob { file: _, responder } => {
                                responder.send(&mut Ok(false)).unwrap();
                            }
                            NeededBlobsRequest::GetMissingBlobs { iterator, control_handle: _ } => {
                                let mut stream = iterator.into_stream().unwrap();
                                let BlobInfoIteratorRequest::Next { responder } =
                                    stream.next().await.unwrap().unwrap();
                                responder.send(&mut std::iter::empty()).unwrap();
                            }
                            r => panic!("Unexpected request: {:?}", r),
                        }
                    }
                    responder.send(&mut Ok(())).unwrap();
                }
                r => panic!("Unexpected request: {:?}", r),
            }
        }
    }

    fn get_test_package_resolver_with_hash(hash: &str) -> (MockResolver, tempfile::TempDir) {
        let dir = tempfile::tempdir().unwrap();
        std::fs::write(dir.path().join("meta"), hash).unwrap();
        let proxy = fuchsia_fs::open_directory_in_namespace(
            dir.path().to_str().unwrap(),
            fuchsia_fs::OpenFlags::RIGHT_READABLE,
        )
        .unwrap();
        let pkg_dir = PackageDirectory::from_proxy(proxy);
        let package_resolver = MockResolver::new(move |_url| {
            let pkg_dir = pkg_dir.clone();
            async move { Ok((pkg_dir, pkg::ResolutionContext::new(vec![]))) }
        });
        (package_resolver, dir)
    }
    fn get_default_cup_response() -> Vec<u8> {
        get_cup_response_with_name(&format!("package?hash={TEST_HASH}"))
    }
    fn get_cup_response_with_name(package_name: &str) -> Vec<u8> {
        let response = serde_json::json!({"response":{
          "server": "prod",
          "protocol": "3.0",
          "app": [{
            "appid": "appid",
            "cohortname": "stable",
            "status": "ok",
            "updatecheck": {
              "status": "ok",
              "urls":{
                "url":[
                  {"codebase": "fuchsia-pkg://example.com/"},
                ]
              },
              "manifest": {
                "version": "1.2.3.4",
                "actions": {
                  "action": [],
                },
                "packages": {
                  "package": [
                    {
                     "name": package_name,
                     "required": true,
                     "fp": "",
                    }
                  ],
                },
              }
            }
          }],
        }});
        serde_json::to_vec(&response).unwrap()
    }

    fn make_cup_data(cup_response: &[u8]) -> CupData {
        let (priv_key, public_key) = make_keys_for_test();
        let public_key_id: PublicKeyId = make_default_public_key_id_for_test();
        let public_keys = make_public_keys_for_test(public_key_id, public_key);
        let cup_handler = StandardCupv2Handler::new(&public_keys);
        let request = Request::default();
        let mut intermediate = make_standard_intermediate_for_test(request);
        let request_metadata = cup_handler.decorate_request(&mut intermediate).unwrap();
        let request_body = intermediate.serialize_body().unwrap();
        let expected_signature: Vec<u8> =
            make_expected_signature_for_test(&priv_key, &request_metadata, &cup_response);
        CupData::builder()
            .key_id(public_key_id)
            .nonce(request_metadata.nonce)
            .request(request_body)
            .response(cup_response)
            .signature(expected_signature)
            .build()
    }

    async fn write_persistent_fidl(
        data_proxy: &fio::DirectoryProxy,
        packages: impl IntoIterator<Item = (impl std::fmt::Display, CupData)>,
    ) {
        let file_proxy = fuchsia_fs::directory::open_file(
            data_proxy,
            EAGER_PACKAGE_PERSISTENT_FIDL_NAME,
            fio::OpenFlags::RIGHT_WRITABLE | fio::OpenFlags::CREATE,
        )
        .await
        .unwrap();
        let mut packages = PersistentEagerPackages {
            packages: Some(
                packages
                    .into_iter()
                    .map(|(url, cup)| PersistentEagerPackage {
                        url: Some(fpkg::PackageUrl { url: url.to_string() }),
                        cup: Some(cup.into()),
                        ..PersistentEagerPackage::EMPTY
                    })
                    .collect(),
            ),
            ..PersistentEagerPackages::EMPTY
        };
        fuchsia_fs::write_file_fidl(&file_proxy, &mut packages).await.unwrap();
    }

    #[test]
    fn parse_eager_package_configs_json() {
        use std::convert::TryInto;

        let public_keys = PublicKeys {
            latest: PublicKeyAndId {
                id: 123.try_into().unwrap(),
                key: make_default_public_key_for_test(),
            },
            historical: vec![],
        };

        let json = serde_json::json!(
        {
            "packages":
            [
                {
                    "url": "fuchsia-pkg://example.com/package",
                    "executable": true,
                    "public_keys": {
                        "latest": {
                            "id": 123,
                            "key": RAW_PUBLIC_KEY_FOR_TEST,
                        },
                        "historical": []
                    }
                },
                {
                    "url": "fuchsia-pkg://example.com/package2",
                    "executable": false,
                    "public_keys": {
                        "latest": {
                            "id": 123,
                            "key": RAW_PUBLIC_KEY_FOR_TEST,
                        },
                        "historical": []
                    }
                },
                {
                    "url": "fuchsia-pkg://example.com/package3",
                    "public_keys": {
                        "latest": {
                            "id": 123,
                            "key": RAW_PUBLIC_KEY_FOR_TEST,
                        },
                        "historical": []
                    }
                }
            ]
        });
        assert_eq!(
            serde_json::from_value::<EagerPackageConfigs>(json).unwrap(),
            EagerPackageConfigs {
                packages: vec![
                    EagerPackageConfig {
                        url: "fuchsia-pkg://example.com/package".parse().unwrap(),
                        executable: true,
                        public_keys: public_keys.clone(),
                    },
                    EagerPackageConfig {
                        url: "fuchsia-pkg://example.com/package2".parse().unwrap(),
                        executable: false,
                        public_keys: public_keys.clone(),
                    },
                    EagerPackageConfig {
                        url: "fuchsia-pkg://example.com/package3".parse().unwrap(),
                        executable: false,
                        public_keys,
                    },
                ]
            }
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_get_eager_package_with_empty_config() {
        let config = EagerPackageConfigs { packages: Vec::new() };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, _) = get_mock_pkg_cache();
        let manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;

        assert!(manager.packages.is_empty());

        for url in [
            "fuchsia-pkg://example2.com/package",
            "fuchsia-pkg://example.com/package3",
            "fuchsia-pkg://example.com/package?hash=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
        ] {
            assert_matches!(manager.get_package_dir(&url.parse().unwrap()), Ok(None));
        }
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_resolve_pinned_hash_mismatch() {
        let pinned_url = PinnedAbsolutePackageUrl::from_unpinned(
            TEST_URL.parse().unwrap(),
            TEST_HASH.parse().unwrap(),
        );
        assert_matches!(
            EagerPackageManager::resolve_pinned(&get_test_package_resolver(), pinned_url).await,
            Err(ResolvePinnedError::HashMismatch(_))
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_load_persistent_eager_packages() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let url2 = UnpinnedAbsolutePackageUrl::parse("fuchsia-pkg://example.com/package2").unwrap();
        let config = EagerPackageConfigs {
            packages: vec![
                EagerPackageConfig {
                    url: url.clone(),
                    executable: true,
                    public_keys: make_default_public_keys_for_test(),
                },
                EagerPackageConfig {
                    url: url2.clone(),
                    executable: false,
                    public_keys: make_default_public_keys_for_test(),
                },
            ],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, pkg_cache_stream) = get_mock_pkg_cache();

        let data_dir = tempfile::tempdir().unwrap();
        let data_proxy = fuchsia_fs::open_directory_in_namespace(
            data_dir.path().to_str().unwrap(),
            fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
        )
        .unwrap();

        let cup1_response: Vec<u8> = get_default_cup_response();
        let cup1: CupData = make_cup_data(&cup1_response);
        let cup2_response =
            get_cup_response_with_name(&format!("package2?hash={}", "1".repeat(64)));
        // this will fail to resolve because hash doesn't match
        let cup2: CupData = make_cup_data(&cup2_response);
        write_persistent_fidl(
            &data_proxy,
            [
                // packages can be out of order
                (url2.clone(), cup2.clone()),
                // bad packages won't break loading of other valid packages
                (
                    UnpinnedAbsolutePackageUrl::parse("fuchsia-pkg://unknown/package").unwrap(),
                    cup1.clone(),
                ),
                // If CupData is empty, we should skip and log the error but not crash or fail.
                (url.clone(), CupData::builder().build()),
                (url.clone(), cup1.clone()),
            ],
        )
        .await;
        let (manager, ()) = future::join(
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, Some(data_proxy)),
            handle_pkg_cache(pkg_cache_stream),
        )
        .await;
        assert_matches!(
            manager
                .get_package_dir(&"fuchsia-pkg://example.com/non-eager-package".parse().unwrap()),
            Ok(None)
        );
        assert!(manager.packages[&url].package_directory.is_some());
        assert!(manager.get_package_dir(&url.clone().into()).unwrap().is_some());
        assert_eq!(manager.packages[&url].cup, Some(cup1));
        assert!(manager.packages[&url2].package_directory.is_none());
        assert_matches!(manager.get_package_dir(&url2.clone().into()), Err(_));
        // cup is still loaded even if resolve fails
        assert_eq!(manager.packages[&url2].cup, Some(cup2));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_load_persistent_eager_packages_signature_invalid() {
        // We intentionally stage a mismatch between the PublicKeys used
        // to configure the EagerPackageManager (latest.key_id = 777) and the
        // PublicKeys generated in make_cup_data() (latest.key_id = 123456789),
        // which are written to persistent fidl and which we attempt to validate
        // at startup.

        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();

        let mut public_keys = make_default_public_keys_for_test();
        public_keys.latest.id = 777;

        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig { url: url.clone(), executable: true, public_keys }],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, pkg_cache_stream) = get_mock_pkg_cache();

        let data_dir = tempfile::tempdir().unwrap();
        let data_proxy = fuchsia_fs::open_directory_in_namespace(
            data_dir.path().to_str().unwrap(),
            fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
        )
        .unwrap();

        let cup: CupData = make_cup_data(&get_default_cup_response());
        write_persistent_fidl(&data_proxy, [(url.clone(), cup.clone())]).await;
        let (manager, ()) = future::join(
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, Some(data_proxy)),
            handle_pkg_cache(pkg_cache_stream),
        )
        .await;
        // This fails to load, and we log "failed to load persistent eager
        // package: could not verify cup signature
        // VerificationError(SpecifiedPublicKeyIdMissing)".
        assert!(manager.get_package_dir(&url.clone().into()).is_err());
        assert!(manager.packages[&url].package_directory.is_none());
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_write() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let (package_resolver, _test_dir) = get_test_package_resolver_with_hash(TEST_HASH);
        let (pkg_cache, pkg_cache_stream) = get_mock_pkg_cache();

        let data_dir = tempfile::tempdir().unwrap();
        let data_proxy = fuchsia_fs::open_directory_in_namespace(
            data_dir.path().to_str().unwrap(),
            fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
        )
        .unwrap();
        let mut manager = EagerPackageManager::from_config(
            config.clone(),
            package_resolver.clone(),
            pkg_cache.clone(),
            Some(Clone::clone(&data_proxy)),
        )
        .await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        manager
            .cup_write(&fpkg::PackageUrl { url: TEST_PINNED_URL.into() }, cup.clone().into())
            .await
            .unwrap();
        assert!(manager.packages[&url].package_directory.is_some());
        assert_eq!(manager.packages[&url].cup, Some(cup.clone()));

        // create a new manager which should load the persisted cup data.
        let (manager2, ()) = future::join(
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, Some(data_proxy)),
            handle_pkg_cache(pkg_cache_stream),
        )
        .await;
        assert!(manager2.packages[&url].package_directory.is_some());
        assert_eq!(manager2.packages[&url].cup, Some(cup));
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_write_persist_fail() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let (package_resolver, _test_dir) = get_test_package_resolver_with_hash(TEST_HASH);
        let (pkg_cache, _) = get_mock_pkg_cache();

        let mut manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        assert_matches!(
            manager.cup_write(&fpkg::PackageUrl { url: TEST_PINNED_URL.into() }, cup.into()).await,
            Err(CupWriteError::Persist(_))
        );
        assert!(manager.packages[&url].package_directory.is_none());
        assert_eq!(manager.packages[&url].cup, None);
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_write_omaha_response_different_url() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let (package_resolver, _test_dir) = get_test_package_resolver_with_hash(TEST_HASH);
        let (pkg_cache, _) = get_mock_pkg_cache();

        let mut manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        assert_matches!(
            manager
                .cup_write(&fpkg::PackageUrl { url: format!("{url}?hash=beefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead") }, cup.into())
                .await,
            Err(CupWriteError::CupResponseURLNotFound)
        );
        assert!(manager.packages[&url].package_directory.is_none());
        assert!(manager.packages[&url].cup.is_none());
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_write_unknown_url() {
        let url = UnpinnedAbsolutePackageUrl::parse("fuchsia-pkg://example.com/package2").unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, _) = get_mock_pkg_cache();

        let mut manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        assert_matches!(
            manager.cup_write(&fpkg::PackageUrl { url: TEST_PINNED_URL.into() }, cup.into()).await,
            Err(CupWriteError::UnknownURL(_))
        );
        assert!(manager.packages[&url].package_directory.is_none());
        assert!(manager.packages[&url].cup.is_none());
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_get_info() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, _) = get_mock_pkg_cache();

        let mut manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        manager.packages.get_mut(&url).unwrap().cup = Some(cup);
        let (version, channel) =
            manager.cup_get_info(&fpkg::PackageUrl { url: TEST_URL.into() }).await.unwrap();
        assert_eq!(version, "1.2.3.4");
        assert_eq!(channel, "stable");
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_get_info_not_available() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, _) = get_mock_pkg_cache();

        let manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        assert_matches!(
            manager.cup_get_info(&fpkg::PackageUrl { url: TEST_URL.into() }).await,
            Err(CupGetInfoError::CupDataNotAvailable)
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_get_info_unknown_url() {
        let url = UnpinnedAbsolutePackageUrl::parse(TEST_URL).unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, _) = get_mock_pkg_cache();

        let mut manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        manager.packages.get_mut(&url).unwrap().cup = Some(cup);
        assert_matches!(
            manager
                .cup_get_info(&fpkg::PackageUrl {
                    url: "fuchsia-pkg://example.com/package2".into()
                })
                .await,
            Err(CupGetInfoError::UnknownURL(_))
        );
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_cup_get_info_omaha_response_different_url() {
        let url = UnpinnedAbsolutePackageUrl::parse("fuchsia-pkg://example.com/package2").unwrap();
        let config = EagerPackageConfigs {
            packages: vec![EagerPackageConfig {
                url: url.clone(),
                executable: true,
                public_keys: make_default_public_keys_for_test(),
            }],
        };
        let package_resolver = get_test_package_resolver();
        let (pkg_cache, _) = get_mock_pkg_cache();

        let mut manager =
            EagerPackageManager::from_config(config, package_resolver, pkg_cache, None).await;
        let cup: CupData = make_cup_data(&get_default_cup_response());
        manager.packages.get_mut(&url).unwrap().cup = Some(cup);
        assert_matches!(
            manager
                .cup_get_info(&fpkg::PackageUrl {
                    url: "fuchsia-pkg://example.com/package2".into()
                })
                .await,
            Err(CupGetInfoError::CupResponseURLNotFound)
        );
    }
}
