// Copyright 2020 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 {
    super::*,
    crate::{merkle_str, pinned_pkg_url},
    fidl_fuchsia_update_installer_ext::{
        FetchFailureReason, PrepareFailureReason, Progress, State, UpdateInfo,
        UpdateInfoAndProgress,
    },
    pretty_assertions::assert_eq,
};

#[fasync::run_singlethreaded(test)]
async fn fails_on_package_resolver_connect_error() {
    let env = TestEnvBuilder::new().unregister_protocol(Protocol::PackageResolver).build().await;

    let result = env.run_update().await;
    assert!(result.is_err(), "system updater succeeded when it should fail");

    assert_eq!(
        env.take_interactions(),
        vec![
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::VerifiedBootMetadata
            }),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::Kernel
            }),
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::QueryConfigurationStatus { configuration: paver::Configuration::A }),
            Paver(PaverEvent::SetConfigurationUnbootable {
                configuration: paver::Configuration::B
            }),
            Paver(PaverEvent::BootManagerFlush),
            // The connect succeeds, so the system updater only notices the resolver is not there when
            // it tries to resolve a package
        ]
    );
}

#[fasync::run_singlethreaded(test)]
async fn fails_on_update_package_fetch_error() {
    let env = TestEnv::builder().build().await;

    env.resolver
        .register_package("update", "upd4t3")
        .add_file("packages.json", make_packages_json([SYSTEM_IMAGE_URL]))
        .add_file("epoch.json", make_epoch_json(SOURCE_EPOCH));

    let system_image_url = SYSTEM_IMAGE_URL;
    env.resolver
        .mock_resolve_failure(system_image_url, fidl_fuchsia_pkg::ResolveError::PackageNotFound);

    let result = env.run_update().await;
    assert!(result.is_err(), "system updater succeeded when it should fail");

    assert_eq!(
        env.get_ota_metrics().await,
        OtaMetrics {
            initiator: metrics::OtaResultAttemptsMetricDimensionInitiator::UserInitiatedCheck
                as u32,
            phase: metrics::OtaResultAttemptsMetricDimensionPhase::PackageDownload as u32,
            status_code: metrics::OtaResultAttemptsMetricDimensionStatusCode::Error as u32,
            target: "".into(),
        }
    );

    assert_eq!(
        env.take_interactions(),
        vec![
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::VerifiedBootMetadata
            }),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::Kernel
            }),
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::QueryConfigurationStatus { configuration: paver::Configuration::A }),
            Paver(PaverEvent::SetConfigurationUnbootable {
                configuration: paver::Configuration::B
            }),
            Paver(PaverEvent::BootManagerFlush),
            PackageResolve(UPDATE_PKG_URL.to_string()),
            Gc,
            PackageResolve(system_image_url.to_string()),
        ]
    );
}

#[fasync::run_singlethreaded(test)]
async fn fails_on_content_package_fetch_error() {
    let env = TestEnv::builder().build().await;

    let pkg1_url = pinned_pkg_url!("package1/0", "aa");
    let pkg2_url = pinned_pkg_url!("package2/0", "00");
    let pkg3_url = pinned_pkg_url!("package3/0", "bb");
    let pkg4_url = pinned_pkg_url!("package4/0", "cc");
    let pkg5_url = pinned_pkg_url!("package5/0", "dd");
    let pkg6_url = pinned_pkg_url!("package6/0", "ee");

    let pkg1 = env.resolver.package("package1", merkle_str!("aa"));
    let pkg3 = env.resolver.package("package3", merkle_str!("bb"));
    let pkg4 = env.resolver.package("package4", merkle_str!("cc"));
    let pkg5 = env.resolver.package("package5", merkle_str!("dd"));

    env.resolver.url("fuchsia-pkg://fuchsia.com/update").resolve(
        &env.resolver
            .package("update", UPDATE_HASH)
            .add_file(
                "packages.json",
                make_packages_json([
                    SYSTEM_IMAGE_URL,
                    pkg1_url,
                    pkg2_url,
                    pkg3_url,
                    pkg4_url,
                    pkg5_url,
                    pkg6_url,
                ]),
            )
            .add_file("epoch.json", make_epoch_json(1)),
    );
    env.resolver
        .url(SYSTEM_IMAGE_URL)
        .resolve(&env.resolver.package("system_image", SYSTEM_IMAGE_HASH));
    let mut handle_pkg1 = env.resolver.url(pkg1_url).block_once();
    let mut handle_pkg2 = env.resolver.url(pkg2_url).block_once();
    let mut handle_pkg3 = env.resolver.url(pkg3_url).block_once();
    let mut handle_pkg4 = env.resolver.url(pkg4_url).block_once();
    let mut handle_pkg5 = env.resolver.url(pkg5_url).block_once();
    env.resolver.url(pkg6_url).resolve(&env.resolver.package("package6", merkle_str!("ee")));

    let ((), ()) = future::join(
        async {
            let result = env.run_update().await;
            assert!(result.is_err(), "system updater succeeded when it should fail");
        },
        async move {
            // The system updater will try to resolve 5 packages concurrently. Wait for the
            // requests to come in.
            handle_pkg1.wait().await;
            handle_pkg2.wait().await;
            handle_pkg3.wait().await;
            handle_pkg4.wait().await;
            handle_pkg5.wait().await;

            // Return a failure for pkg2, and success for the other blocked packages.
            handle_pkg2.fail(fidl_fuchsia_pkg::ResolveError::PackageNotFound).await;

            handle_pkg1.resolve(&pkg1).await;
            handle_pkg3.resolve(&pkg3).await;
            handle_pkg4.resolve(&pkg4).await;
            handle_pkg5.resolve(&pkg5).await;
        },
    )
    .await;

    assert_eq!(
        env.get_ota_metrics().await,
        OtaMetrics {
            initiator: metrics::OtaResultAttemptsMetricDimensionInitiator::UserInitiatedCheck
                as u32,
            phase: metrics::OtaResultAttemptsMetricDimensionPhase::PackageDownload as u32,
            status_code: metrics::OtaResultAttemptsMetricDimensionStatusCode::Error as u32,
            target: "".into(),
        }
    );

    assert_eq!(
        env.take_interactions(),
        vec![
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::VerifiedBootMetadata
            }),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::Kernel
            }),
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::QueryConfigurationStatus { configuration: paver::Configuration::A }),
            Paver(PaverEvent::SetConfigurationUnbootable {
                configuration: paver::Configuration::B
            }),
            Paver(PaverEvent::BootManagerFlush),
            PackageResolve(UPDATE_PKG_URL.to_string()),
            Gc,
            PackageResolve(SYSTEM_IMAGE_URL.to_string()),
            PackageResolve(pkg1_url.to_string()),
            PackageResolve(pkg2_url.to_string()),
            PackageResolve(pkg3_url.to_string()),
            PackageResolve(pkg4_url.to_string()),
            PackageResolve(pkg5_url.to_string()),
            // pkg6_url is never resolved, as pkg2's resolve finishes first with an error.
        ]
    );
}

#[fasync::run_singlethreaded(test)]
async fn fails_when_package_cache_sync_fails() {
    let env = TestEnv::builder().build().await;
    env.cache_service.set_sync_response(Err(Status::INTERNAL));
    env.resolver
        .register_package("update", "upd4t3")
        .add_file("packages.json", make_packages_json([SYSTEM_IMAGE_URL]))
        .add_file("epoch.json", make_epoch_json(SOURCE_EPOCH));
    env.resolver
        .url(SYSTEM_IMAGE_URL)
        .resolve(&env.resolver.package("system_image/0", SYSTEM_IMAGE_HASH));

    let result = env.run_update().await;

    assert!(result.is_err(), "system updater succeeded when it should fail");

    assert_eq!(
        env.take_interactions(),
        vec![
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::VerifiedBootMetadata
            }),
            Paver(PaverEvent::ReadAsset {
                configuration: paver::Configuration::A,
                asset: paver::Asset::Kernel
            }),
            Paver(PaverEvent::QueryCurrentConfiguration),
            Paver(PaverEvent::QueryConfigurationStatus { configuration: paver::Configuration::A }),
            Paver(PaverEvent::SetConfigurationUnbootable {
                configuration: paver::Configuration::B
            }),
            Paver(PaverEvent::BootManagerFlush),
            PackageResolve(UPDATE_PKG_URL.to_string()),
            Gc,
            PackageResolve(SYSTEM_IMAGE_URL.to_string()),
            BlobfsSync,
        ]
    );
}

/// Verifies that when we fail to resolve the update package, we get a Prepare failure with the
/// expected `PrepareFailureReason`.
async fn assert_prepare_failure_reason(
    resolve_error: fidl_fuchsia_pkg::ResolveError,
    expected_reason: PrepareFailureReason,
) {
    let env = TestEnv::builder().build().await;
    env.resolver.mock_resolve_failure(UPDATE_PKG_URL, resolve_error);

    let mut attempt = env.start_update().await.unwrap();

    assert_eq!(attempt.next().await.unwrap().unwrap(), State::Prepare);
    assert_eq!(attempt.next().await.unwrap().unwrap(), State::FailPrepare(expected_reason));
}

#[fasync::run_singlethreaded(test)]
async fn prepare_failure_reason_out_of_space() {
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::NoSpace,
        PrepareFailureReason::OutOfSpace,
    )
    .await;
}

#[fasync::run_singlethreaded(test)]
async fn prepare_failure_reason_internal() {
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::AccessDenied,
        PrepareFailureReason::Internal,
    )
    .await;
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::RepoNotFound,
        PrepareFailureReason::Internal,
    )
    .await;
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::Internal,
        PrepareFailureReason::Internal,
    )
    .await;
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::Io,
        PrepareFailureReason::Internal,
    )
    .await;
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::PackageNotFound,
        PrepareFailureReason::Internal,
    )
    .await;
    assert_prepare_failure_reason(
        fidl_fuchsia_pkg::ResolveError::UnavailableBlob,
        PrepareFailureReason::Internal,
    )
    .await;
}

/// Verifies that when we fail to resolve a non-update package, we get a Fetch failure with the
/// expected `FetchFailureReason`.
async fn assert_fetch_failure_reason(
    resolve_error: fidl_fuchsia_pkg::ResolveError,
    expected_reason: FetchFailureReason,
) {
    let env = TestEnv::builder().build().await;
    env.resolver
        .register_package("update", "upd4t3")
        .add_file("packages.json", make_packages_json([SYSTEM_IMAGE_URL]))
        .add_file("epoch.json", make_epoch_json(SOURCE_EPOCH));
    env.resolver.mock_resolve_failure(SYSTEM_IMAGE_URL, resolve_error);

    let mut attempt = env.start_update().await.unwrap();

    let info = UpdateInfo::builder().download_size(0).build();
    let progress = Progress::builder().fraction_completed(0.0).bytes_downloaded(0).build();
    assert_eq!(attempt.next().await.unwrap().unwrap(), State::Prepare);
    assert_eq!(
        attempt.next().await.unwrap().unwrap(),
        State::Fetch(
            UpdateInfoAndProgress::builder().info(info.clone()).progress(progress.clone()).build()
        )
    );
    assert_eq!(
        attempt.next().await.unwrap().unwrap(),
        State::FailFetch(
            UpdateInfoAndProgress::builder()
                .info(info)
                .progress(progress)
                .build()
                .with_reason(expected_reason)
        )
    );
}

#[fasync::run_singlethreaded(test)]
async fn fetch_failure_reason_out_of_space() {
    assert_fetch_failure_reason(
        fidl_fuchsia_pkg::ResolveError::NoSpace,
        FetchFailureReason::OutOfSpace,
    )
    .await;
}

#[fasync::run_singlethreaded(test)]
async fn fetch_failure_reason_internal() {
    assert_fetch_failure_reason(
        fidl_fuchsia_pkg::ResolveError::AccessDenied,
        FetchFailureReason::Internal,
    )
    .await;
    assert_fetch_failure_reason(
        fidl_fuchsia_pkg::ResolveError::RepoNotFound,
        FetchFailureReason::Internal,
    )
    .await;
    assert_fetch_failure_reason(
        fidl_fuchsia_pkg::ResolveError::Internal,
        FetchFailureReason::Internal,
    )
    .await;
    assert_fetch_failure_reason(fidl_fuchsia_pkg::ResolveError::Io, FetchFailureReason::Internal)
        .await;
    assert_fetch_failure_reason(
        fidl_fuchsia_pkg::ResolveError::PackageNotFound,
        FetchFailureReason::Internal,
    )
    .await;
    assert_fetch_failure_reason(
        fidl_fuchsia_pkg::ResolveError::UnavailableBlob,
        FetchFailureReason::Internal,
    )
    .await;
}
