// Copyright 2023 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::blob::BlobOpenError;
use super::bootfs::AdditionalBootConfigurationError;
use super::bootfs::BootfsPackageError;
use super::bootfs::BootfsPackageIndexError;
use super::bootfs::ComponentManagerConfigurationError;
use cm_rust::CapabilityDecl;
use cm_rust::ComponentDecl;
use dyn_clone::clone_trait_object;
use dyn_clone::DynClone;
use fuchsia_url as furl;
use std::cmp;
use std::collections::HashMap;
use std::fmt;
use std::fmt::Debug;
use std::fmt::Display;
use std::hash;
use std::io::Read;
use std::io::Seek;
use std::path;
use thiserror::Error;

/// The type of readable, seekable objects returned by API interfaces.
pub trait ReaderSeeker: Read + Seek {}

impl<RS: Read + Seek> ReaderSeeker for RS {}

/// The type of paths on API interfaces.
pub trait Path: AsRef<path::Path> + DynClone {}

impl<P: AsRef<path::Path> + DynClone> Path for P {}

clone_trait_object!(Path);

impl Debug for dyn Path {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}

impl Display for dyn Path {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}

impl PartialEq for dyn Path {
    fn eq(&self, other: &dyn Path) -> bool {
        // Compare `dyn Path` instances as `std::path::Path` references.
        self.as_ref() == other.as_ref()
    }
}

impl Eq for dyn Path {}

impl hash::Hash for dyn Path {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.as_ref().hash(state)
    }
}

/// Instance of the scrutiny framework backed by a particular set of artifacts.
pub trait Scrutiny {
    /// Accessor for high-level data about the Fuchsia system composition.
    fn system(&self) -> Box<dyn System>;

    /// Accessor for the system's component manager configuration.
    fn component_manager(&self) -> Box<dyn ComponentManager>;

    /// Accessor for high-level information about this [`Scrutiny`] instance's data sources.
    fn data_sources(&self) -> Box<dyn Iterator<Item = Box<dyn DataSource>>>;

    /// Iterate over all blobs from all system data sources.
    fn blobs(&self) -> Box<dyn Iterator<Item = Box<dyn Blob>>>;

    /// Iterate over all packages from all system data sources.
    fn packages(&self) -> Box<dyn Iterator<Item = Box<dyn Package>>>;

    /// Iterate over all component manifests in the system.
    fn component_manifests(&self) -> Box<dyn Iterator<Item = ComponentDecl>>;

    /// Iterate over all component instances in the system. Note that a component instance is a
    /// component situated at a particular point in the system's component tree.
    fn component_instances(&self) -> Box<dyn Iterator<Item = Box<dyn ComponentInstance>>>;
}

/// High-level metadata about the system inspected by a [`Scrutiny`] instance.
pub trait System: DynClone {
    /// The kind of Fuchsia system under inspection.
    fn variant(&self) -> SystemVariant;

    /// The build directory associated with the system build.
    fn build_dir(&self) -> Box<dyn Path>;

    /// Accessor for the system's Zircon Boot Image (ZBI).
    fn zbi(&self) -> Box<dyn Zbi>;

    /// Accessor for the system's update package.
    fn update_package(&self) -> Box<dyn UpdatePackage>;

    /// Accessor for the system's kernel command-line flags.
    fn kernel_flags(&self) -> Box<dyn KernelFlags>;

    /// Accessor for the system's Verified Boot Metadata (vbmeta).
    fn vb_meta(&self) -> Box<dyn VbMeta>;
}

clone_trait_object!(System);

/// The kind of Fuchsia system that should be inspected by a [`Scrutiny`] instance. The variant determines a
/// variety of strategies used to locate system artifacts. For example, the location of the Zircon Boot Image
/// (ZBI) in the Update Package is different for `Main` and `Recovery` systems.
#[derive(Clone)]
pub enum SystemVariant {
    /// The usual system layout that would be installed on the "A/B" device partitions.
    Main,
    /// The recovery system layout that would be installed on a "recovery" device partition.
    Recovery,
}

// TODO(https://fxbug.dev/42063457): This is over-fitted to the "inspect bootfs" use case, and should probably be in terms of
// the various types of ZBI sections.

/// Model of the system's Zircon Boot Image (ZBI) used for Zircon kernel to userspace bootstrapping
/// (userboot). See https://fuchsia.dev/fuchsia-src/concepts/process/userboot for details.
pub trait Zbi: DynClone {
    /// Accessor for bootfs.
    fn bootfs(&self) -> Result<Box<dyn Bootfs>, ZbiError>;
}

clone_trait_object!(Zbi);

#[derive(Debug, Error)]
pub enum ZbiError {
    #[error("expected to find exactly 1 bootfs section in zbi, but found {num_sections}")]
    BootfsSections { num_sections: usize },
    #[error("failed to parse bootfs image in zbi at path {path:?}: {error}")]
    ParseBootfs { path: Box<dyn Path>, error: anyhow::Error },
}

/// Model of the read-only boot filesystem, containing files needed in early boot.
/// The filesystem is a list of filenames together with, for each filename, the size and
/// offset of the file.
/// See https://fuchsia.dev/fuchsia-src/concepts/process/userboot#bootfs for details.
pub trait Bootfs: DynClone {
    /// Iterator over all contents of bootfs by path, with each file delivered as a `Blob`
    /// implementation.
    ///
    /// Some files are serialized instances of particular data types; for example,
    /// configuration files or packages. This iterator provides those files in raw format
    /// together with all other contents of bootfs, but other `Bootfs` trait methods may
    /// provide an object-oriented view of the same files (after parsing and validating
    /// the raw data). For example, the component manager configuration file is provided
    /// in raw form via `content_blobs()`, and as an implementation of the
    /// `ComponentManagerConfiguration` API via `compoennt_manager_configuration()`.
    fn content_blobs(&self) -> Box<dyn Iterator<Item = (Box<dyn Path>, Box<dyn Blob>)>>;

    /// Accessor for the system's additional boot configuration file.
    fn additional_boot_configuration(
        &self,
    ) -> Result<Box<dyn AdditionalBootConfiguration>, BootfsError>;

    /// Accessor for the system's component manager configuration.
    fn component_manager_configuration(
        &self,
    ) -> Result<Box<dyn ComponentManagerConfiguration>, BootfsError>;

    /// Iterate over all packages in bootfs.
    fn packages(&self) -> Result<Box<dyn Iterator<Item = Box<dyn Package>>>, BootfsError>;
}

clone_trait_object!(Bootfs);

#[derive(Debug, Error)]
pub enum BootfsError {
    #[error("failed to instantiate additional boot configuration: {0}")]
    AdditionalBootConfiguration(#[from] AdditionalBootConfigurationError),
    #[error("failed to instantiate component manager configuration: {0}")]
    ComponentManagerConfiguration(#[from] ComponentManagerConfigurationError),
    #[error("failed to read bootfs package index: {0}")]
    PackageIndex(#[from] BootfsPackageIndexError),
    #[error("failed to instantiate bootfs package: {0}")]
    Packages(#[from] BootfsPackageError),
}

/// Kernel command-line flags. See https://fuchsia.dev/fuchsia-src/reference/kernel/kernel_cmdline
/// for details.
pub trait KernelFlags {
    /// Get the kernel command-line flag named `key`, or `None` if the flag does not exist in among
    /// this instance of kernel command-line flags.
    fn get(&self, key: &str) -> Option<&str>;

    /// Iterate over all kernel command-line flags specified on this instance.
    fn iter(&self) -> Box<dyn Iterator<Item = (String, String)>>;
}

// TODO(https://fxbug.dev/42063457): What should this API look like?

/// Model of the Verified Boot Metadata (vbmeta).
pub trait VbMeta {}

/// Additional boot configuration file key/value pairs. This configuration file is passed to the
/// component manager, and is combined with configuration set in [`KernelFlags`] and
/// [`VbMeta`] to determine various configuration parameters for booting the Fuchsia system on the
/// device.
///
/// See https://fuchsia.dev/fuchsia-src/reference/kernel/kernel_cmdline for more details about
/// how the configuration is used, and see https://fuchsia.dev/fuchsia-src/gen/boot-options for
/// the set of valid options.
pub trait AdditionalBootConfiguration {
    /// Get the value associated with `key`, or `None` if the key does not exist in in the
    /// underlying device configuration file.
    fn get(&self, key: &str) -> Option<&str>;

    /// Iterate over all key/value pairs specified on this instance.
    fn iter(&self) -> Box<dyn Iterator<Item = (String, String)>>;
}

/// Metadata about the component manager on a system.
pub trait ComponentManager {
    /// Accessor for this component manager's configuration.
    fn configuration(&self) -> Box<dyn ComponentManagerConfiguration>;

    /// Capabilities the system provides to the component manager.
    fn namespace_capabilities(&self) -> Box<dyn Iterator<Item = CapabilityDecl>>;

    /// Capabilities the component manager provides to all components that it manages.
    fn builtin_capabilities(&self) -> Box<dyn Iterator<Item = CapabilityDecl>>;
}

// TODO(https://fxbug.dev/42063457): What should this API look like? This is just a starting point to
// get something plumbed through from the data source.

/// Model of the component manager configuration. This configuration file controls various
/// aspects of component manager's execution, including capability routing policy and
/// logging behavior.
///
/// For details about the role of component manager
/// in the system, see https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manager.
///
/// See //sdk/fidl/fuchsia.component.internal/config.fidl for the (internal) FIDL format that
/// should back implementations of this trait.
pub trait ComponentManagerConfiguration {
    /// Whether Component Manager will run in debug mode.
    /// See //sdk/fidl/fuchsia.component.internal/config.fidl for details.
    fn debug(&self) -> bool;
}

/// Model of a data source that a [`Scrutiny`] instance is using as a source of truth about the
/// underlying system. This type is used for interrogating where a Fuchsia abstraction such as a
/// blob, package, or component came from (in terms of host filesystem artifacts). This is useful,
/// for example, in constructing error messages related to failed operations over a Fuchsia
/// abstraction.
pub trait DataSource: Debug + DynClone {
    /// The kind of artifact that this data source represents.
    fn kind(&self) -> DataSourceKind;

    /// The parent data source in the case of nested data sources. For example, this may refer to an
    /// FVM volume that contains a blobfs archive.
    fn parent(&self) -> Option<Box<dyn DataSource>>;

    /// Children data sources in the case of nested data sources.
    fn children(&self) -> Box<dyn Iterator<Item = Box<dyn DataSource>>>;

    /// The local path to this data source. Generally only applicable to data sources that have no
    /// parent.
    fn path(&self) -> Option<Box<dyn Path>>;

    /// The version of the underlying format of the data source.
    fn version(&self) -> DataSourceVersion;
}

clone_trait_object!(DataSource);

/// Computes equality of data exposed by two [`DataSource`] objects and their descendants.
fn descendants_eq(a: &dyn DataSource, b: &dyn DataSource) -> bool {
    if !data_source_shallow_eq(a, b) {
        return false;
    }

    let a_children: Vec<_> = a.children().collect();
    let b_children: Vec<_> = b.children().collect();
    if a_children.len() != b_children.len() {
        return false;
    }
    for (a_child, b_child) in a_children.into_iter().zip(b_children.into_iter()) {
        if !descendants_eq(a_child.as_ref(), b_child.as_ref()) {
            return false;
        }
    }

    true
}

/// Computes equality of [`DataSource`] ancestor objects of `a` and `b`, not including `a` and `b`
/// themselves.
fn ancestors_eq(a: &dyn DataSource, b: &dyn DataSource) -> bool {
    match (a.parent(), b.parent()) {
        (None, None) => true,
        (Some(_), None) | (None, Some(_)) => false,
        (Some(a_parent), Some(b_parent)) => {
            if !data_source_shallow_eq(a_parent.as_ref(), b_parent.as_ref()) {
                false
            } else {
                ancestors_eq(a_parent.as_ref(), b_parent.as_ref())
            }
        }
    }
}

/// Computes whether `a` and `b` appear at the same position among sibling [`DataSource`] objects in
/// their associated trees of data sources.
fn data_source_child_placement_eq(a: &dyn DataSource, b: &dyn DataSource) -> bool {
    match (a.parent(), b.parent()) {
        (None, None) => true,
        (Some(_), None) | (None, Some(_)) => false,
        (Some(a_parent), Some(b_parent)) => {
            let a_indices: Vec<_> = a_parent
                .children()
                .enumerate()
                .filter(|(_, child)| data_source_shallow_eq(a, child.as_ref()))
                .map(|(index, _)| index)
                .collect();
            if a_indices.len() != 1 {
                return false;
            }
            let b_indices: Vec<_> = b_parent
                .children()
                .enumerate()
                .filter(|(_, child)| data_source_shallow_eq(b, child.as_ref()))
                .map(|(index, _)| index)
                .collect();
            if b_indices.len() != 1 {
                return false;
            }

            a_indices[0] == b_indices[0]
        }
    }
}

/// Computes equality of all non-parent/child pointer data exposed by two [`DataSource`] objects.
fn data_source_shallow_eq(a: &dyn DataSource, b: &dyn DataSource) -> bool {
    if a.kind() != b.kind() || a.version() != b.version() {
        return false;
    }
    match (a.path(), b.path()) {
        (None, Some(_)) | (Some(_), None) => false,
        (None, None) => true,
        (Some(a_path), Some(b_path)) => {
            let a_ref: &std::path::Path = a_path.as_ref().as_ref();
            let b_ref: &std::path::Path = b_path.as_ref().as_ref();
            a_ref == b_ref
        }
    }
}

impl PartialEq for dyn DataSource {
    fn eq(&self, other: &dyn DataSource) -> bool {
        // To be deemed equal, `self` and `other` must define identical subtrees, have the same
        // ancestor data sources, and appear at the same position among their sibling data sources.
        descendants_eq(self, other)
            && ancestors_eq(self, other)
            && data_source_child_placement_eq(self, other)
    }
}

impl Eq for dyn DataSource {}

/// Kinds of artifacts that may constitute a source of truth for a [`Scrutiny`] instance reasoning
/// about a built Fuchsia system.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum DataSourceKind {
    /// A product bundle directory that contains various artifacts at known paths within the
    /// directory.
    ProductBundle,
    /// A TUF repository containing metadata and blobs.
    TufRepository,
    /// A blobfs archive (typically named "blob.blk" in Fuchsia builds). For details about blobfs
    /// itself, see https://fuchsia.dev/fuchsia-src/concepts/filesystems/blobfs.
    BlobfsArchive,
    /// A directory of blob files that are named after their Fuchsia merkle root hashes.
    BlobDirectory,
    /// A Fuchsia package. See https://fuchsia.dev/fuchsia-src/concepts/packages/package for
    /// details.
    Package,
    /// An update package that designates a set of packages that constitute an over-the-air (OTA)
    /// system software update. See https://fuchsia.dev/fuchsia-src/concepts/packages/update_pkg
    /// for details.
    UpdatePackage,
    /// A Fuchsia Volume Manager (FVM) filesystem volume file. See
    /// https://fuchsia.dev/fuchsia-src/concepts/filesystems/filesystems#fvm for details.
    FvmVolume,
    /// A Zircon Boot Image (ZBI) file.
    Zbi,

    /// Multiple kinds are associated with underlying data source(s).
    Multiple(Vec<DataSourceKind>),

    // TODO(https://fxbug.dev/42063457): Are there other data sources to consume?
    /// An artifact that was passed to a [`Scrutiny`] instance, but either its kind was not
    /// recognized, or the artifact was not a well-formed instance of the kind passed in.
    Unknown,
}

// TODO(https://fxbug.dev/42063457): What varieties of versioning do formats need?

/// A version identifier associated with an artifact or unit of software used to interpret
/// artifacts.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum DataSourceVersion {
    /// Either no version information is available, or the information was malformed.
    Unknown,
}

/// A content-addressed file.
pub trait Blob {
    /// Accessor for the hash (i.e., content-addressed identity) of this file.
    fn hash(&self) -> Box<dyn Hash>;

    /// Gets a readable and seekable file content access API.
    ///
    /// # Panics
    ///
    /// Some blob sources may not support concurrent invocations of `Blob::reader_seeker`.
    fn reader_seeker(&self) -> Result<Box<dyn ReaderSeeker>, BlobError>;

    /// Iterate over the data sources that provide this blob.
    fn data_sources(&self) -> Box<dyn Iterator<Item = Box<dyn DataSource>>>;
}

/// An error encountered executing [`Blob::reader_seeker`].
#[derive(Debug, Error)]
pub enum BlobError {
    #[error("error converting path to string: {path}, from source: {data_sources:?}")]
    Path { path: String, data_sources: Vec<Box<dyn DataSource>> },
    #[error("error reading from blob: {hash}, from directory: {directory}: {io_error_string}")]
    Io { hash: Box<dyn Hash>, directory: Box<dyn Path>, io_error_string: String },
    #[error("error opening blob: {error}")]
    // Note: Blob hash reported by `BlobOpenError`, and omitted here to avoid duplication.
    Open { error: BlobOpenError },
    #[error("error reading meta file {meta_file_path:?}={meta_file_hash} from data sources {data_sources:?}: {error}")]
    Far {
        meta_file_path: Box<dyn Path>,
        meta_file_hash: Box<dyn Hash>,
        data_sources: Vec<Box<dyn DataSource>>,
        error: fuchsia_archive::Error,
    },
}

/// A type that can be reduced to a byte sequence, such as a hash digest.
pub trait AsBytes: Display + Debug {
    fn as_bytes(&self) -> &[u8];
}

impl AsBytes for fuchsia_url::Hash {
    fn as_bytes(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl PartialEq for dyn AsBytes {
    fn eq(&self, other: &dyn AsBytes) -> bool {
        self.as_bytes() == other.as_bytes()
    }
}

impl Eq for dyn AsBytes {}

impl dyn AsBytes {
    fn compare(&self, other: &dyn AsBytes) -> cmp::Ordering {
        self.as_bytes().cmp(other.as_bytes())
    }
}

impl PartialOrd for dyn AsBytes {
    fn partial_cmp(&self, other: &dyn AsBytes) -> Option<cmp::Ordering> {
        Some(self.compare(other))
    }
}

impl Ord for dyn AsBytes {
    fn cmp(&self, other: &dyn AsBytes) -> cmp::Ordering {
        self.compare(other)
    }
}

impl hash::Hash for dyn AsBytes {
    fn hash<H>(&self, state: &mut H)
    where
        H: hash::Hasher,
    {
        state.write(self.as_bytes())
    }
}

/// A content-address of a sequence of bytes. In most production cases, this is a Fuchsia merkle
/// root; see https://fuchsia.dev/fuchsia-src/concepts/packages/merkleroot for details.
pub trait Hash: AsBytes + DynClone + Send + Sync {}

impl<H: AsBytes + DynClone + Send + Sync> Hash for H {}

clone_trait_object!(Hash);

impl dyn Hash {
    fn compare(&self, other: &dyn Hash) -> cmp::Ordering {
        self.as_bytes().cmp(other.as_bytes())
    }
}

impl PartialOrd for dyn Hash {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.compare(other))
    }
}

impl Ord for dyn Hash {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.compare(other)
    }
}

impl PartialEq for dyn Hash {
    fn eq(&self, other: &dyn Hash) -> bool {
        self.as_bytes().eq(other.as_bytes())
    }
}

impl Eq for dyn Hash {}

impl hash::Hash for dyn Hash {
    fn hash<H>(&self, state: &mut H)
    where
        H: hash::Hasher,
    {
        state.write(self.as_bytes())
    }
}

/// Model of a Fuchsia package. See https://fuchsia.dev/fuchsia-src/concepts/packages/package for
/// details.
pub trait Package: DynClone {
    /// Get the content-addressed hash of the package's "meta.far" file.
    fn hash(&self) -> Box<dyn Hash>;

    /// Gets the package's "meta/package" file.
    fn meta_package(&self) -> Box<dyn MetaPackage>;

    /// Gets the package's "meta/contents" file.
    fn meta_contents(&self) -> Box<dyn MetaContents>;

    /// Constructs iterator over blobs designated in the "meta/contents" of the package.
    fn content_blobs(&self) -> Box<dyn Iterator<Item = (Box<dyn Path>, Box<dyn Blob>)>>;

    /// Constructs iterator over files in the package's "meta.far" file. This includes, but is not
    /// limited to "meta/package" and "meta/contents" which have their own structured
    /// APIs.
    fn meta_blobs(&self) -> Box<dyn Iterator<Item = (Box<dyn Path>, Box<dyn Blob>)>>;

    /// Constructs iterator over blobs that appear to be component manifests.
    fn component_manifests(
        &self,
    ) -> Result<Box<dyn Iterator<Item = (Box<dyn Path>, ComponentDecl)>>, PackageComponentsError>;
}

impl PartialEq for dyn Package {
    fn eq(&self, other: &Self) -> bool {
        self.hash() == other.hash()
    }
}

impl Eq for dyn Package {}

impl Debug for dyn Package {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("Package(")?;
        fmt::Debug::fmt(&self.hash(), f)?;
        f.write_str(")")?;
        Ok(())
    }
}

clone_trait_object!(Package);

#[derive(Debug, Error)]
pub enum PackageComponentsError {
    #[error("failed open blob for parsing as component: {0}")]
    Open(#[from] BlobError),
    #[error("failed read blob for parsing as component: {0}")]
    Read(#[from] std::io::Error),
}

// TODO(https://fxbug.dev/42063457): Define API consistent with fuchsia_pkg::MetaPackage.

/// Model of a Fuchsia package's "meta/package" file. See
/// https://fuchsia.dev/fuchsia-src/concepts/packages/package#structure-of-a-package for details.
pub trait MetaPackage {
    fn name(&self) -> &fuchsia_url::PackageName;

    fn variant(&self) -> &fuchsia_url::PackageVariant;
}

impl PartialEq for dyn MetaPackage {
    fn eq(&self, other: &Self) -> bool {
        self.name() == other.name() && self.variant() == other.variant()
    }
}

impl Eq for dyn MetaPackage {}

// TODO(https://fxbug.dev/42063457): Expose data related to fuchsia_pkg::MetaPackage.
impl Debug for dyn MetaPackage {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("MetaPackage")
    }
}

// TODO(https://fxbug.dev/42063457): Define API consistent with fuchsia_pkg::MetaContents.

/// Model of a Fuchsia package's "meta/contents" file. See
/// https://fuchsia.dev/fuchsia-src/concepts/packages/package#structure-of-a-package for details.
pub trait MetaContents {
    /// Returns an iterator over all path -> content hash mappings stored in this "meta/contents"
    /// file.
    fn contents(&self) -> Box<dyn Iterator<Item = (Box<dyn Path>, Box<dyn Hash>)>>;
}

impl PartialEq for dyn MetaContents {
    fn eq(&self, other: &Self) -> bool {
        self.contents().collect::<HashMap<_, _>>() == other.contents().collect::<HashMap<_, _>>()
    }
}

impl Debug for dyn MetaContents {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for (path, hash) in self.contents() {
            f.write_fmt(format_args!("{:?} => {:?}\n", path, hash))?;
        }
        Ok(())
    }
}

pub trait UpdatePackage: Package {
    /// Returns a borrowed listing of package URLs described by this update package.
    fn packages(&self) -> &Vec<furl::PinnedAbsolutePackageUrl>;
}

clone_trait_object!(UpdatePackage);

/// Model for a package resolution strategy. See
/// https://fuchsia.dev/fuchsia-src/get-started/learn/intro/packages#hosting_and_serving_packages
/// for details.
pub trait PackageResolver {
    /// Resolve a package URL to a content-addressed identity (hash).
    fn resolve(&self, url: PackageResolverUrl) -> Option<Box<dyn Hash>>;

    /// Iterate over the variety of package URLs that the resolver would resolve to the package
    /// identity given by `hash`.
    fn aliases(&self, hash: Box<dyn Hash>) -> Box<dyn Iterator<Item = PackageResolverUrl>>;
}

/// The variety of URLs that [`PackageResolver`] can resolve to package hashes.
// TODO(https://fxbug.dev/42063457): Define varieties of URL that PackageResolver supports, choose types
// for those URLs, and have each of these variants wrap a representation of a URL.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum PackageResolverUrl {
    // A URL identifying a package in bootfs.
    Boot(furl::boot_url::BootUrl),
    // A URL identifying a package in a repository.
    Package(furl::PackageUrl),
}

impl PackageResolverUrl {
    pub fn parse(url: &str) -> Result<Self, PackageResolverUrlParseError> {
        match furl::PackageUrl::parse(url) {
            Ok(package_url) => Ok(Self::Package(package_url)),
            Err(package_error) => match furl::boot_url::BootUrl::parse(url) {
                Ok(boot_url) => {
                    if boot_url.resource().is_some() {
                        Err(PackageResolverUrlParseError::BootWithResource)
                    } else {
                        Ok(Self::Boot(boot_url))
                    }
                }
                Err(boot_error) => {
                    Err(PackageResolverUrlParseError::InvalidFormat { package_error, boot_error })
                }
            },
        }
    }
}

#[derive(Debug, Error)]
pub enum PackageResolverUrlParseError {
    #[error("failed to parse as package url: {package_error}; failed to parse as boot url: {boot_error}")]
    InvalidFormat { package_error: furl::errors::ParseError, boot_error: furl::errors::ParseError },
    #[error("boot url that refers to package contains resource")]
    BootWithResource,
}

/// Model for a component resolution strategy. See
/// https://fuchsia.dev/fuchsia-src/concepts/components/v2/capabilities/resolvers for details.
pub trait ComponentResolver {
    /// Resolve a component URL to a content-addressed identity (hash).
    fn resolve(&self, url: ComponentResolverUrl) -> Option<Box<dyn Hash>>;

    /// Iterate over the variety of component URLs that the resolver would resolve to the package
    /// identity given by `hash`.
    fn aliases(&self, hash: Box<dyn Hash>) -> Box<dyn Iterator<Item = ComponentResolverUrl>>;
}

/// The variety of URLs that [`ComponentResolver`] can resolve to component hashes.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ComponentResolverUrl {
    Resource(ResourcePath),
    // A URL identifying a component file in bootfs.
    Boot(furl::boot_url::BootUrl),
    // A URL identifying a component in a package.
    Component(furl::ComponentUrl),
}

impl ComponentResolverUrl {
    pub fn parse(url: &str) -> Result<Self, ComponentResolverUrlParseError> {
        match furl::ComponentUrl::parse(url) {
            Ok(component_url) => Ok(Self::Component(component_url)),
            Err(component_error) => match furl::boot_url::BootUrl::parse(url) {
                Ok(boot_url) => {
                    if boot_url.resource().is_none() {
                        Err(ComponentResolverUrlParseError::BootWithoutResource)
                    } else {
                        Ok(Self::Boot(boot_url))
                    }
                }
                Err(boot_error) => {
                    let mut chars = url.chars();
                    if let Some(first_char) = chars.next() {
                        if first_char == '#' {
                            let resource_path_str = chars.as_str();
                            match furl::validate_resource_path(resource_path_str) {
                                Ok(()) => {
                                    Ok(Self::Resource(ResourcePath(resource_path_str.to_string())))
                                }
                                Err(resource_error) => {
                                    Err(ComponentResolverUrlParseError::ComponentBootAndResource {
                                        component_error,
                                        boot_error,
                                        resource_error,
                                    })
                                }
                            }
                        } else {
                            Err(ComponentResolverUrlParseError::ComponentAndBoot {
                                component_error,
                                boot_error,
                            })
                        }
                    } else {
                        Err(ComponentResolverUrlParseError::ComponentAndBoot {
                            component_error,
                            boot_error,
                        })
                    }
                }
            },
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ResourcePath(String);

#[derive(Debug, Error)]
pub enum ComponentResolverUrlParseError {
    #[error("failed to parse as component url: {component_error}; failed to parse as boot url: {boot_error}; url is not a resource-only URL")]
    ComponentAndBoot {
        component_error: furl::errors::ParseError,
        boot_error: furl::errors::ParseError,
    },
    #[error("failed to parse as component url: {component_error}; failed to parse as boot url: {boot_error}; failed to parse as resource path in resource-only URL: {resource_error}")]
    ComponentBootAndResource {
        component_error: furl::errors::ParseError,
        boot_error: furl::errors::ParseError,
        resource_error: furl::errors::ResourcePathError,
    },
    #[error("boot url that refers to component contains no resource")]
    BootWithoutResource,
}

/// Model of a component instance that appears at a particular location in a component tree. See
/// https://fuchsia.dev/fuchsia-src/concepts/components/v2/topology#component-instances for details.
pub trait ComponentInstance {
    /// Accessor for the component instance identity, or "moniker".
    fn moniker(&self) -> Box<dyn Moniker>;

    /// Accessor for the environment passed to the component instance in the context of the
    /// component tree.
    fn environment(&self) -> Box<dyn Environment>;

    /// Accessor for the underlying component.
    fn component_manifest(&self) -> ComponentDecl;

    /// Accessor for the parent component instance.
    fn parent(&self) -> Box<dyn ComponentInstance>;

    /// Iterate over the children directly under this component in the component tree.
    fn children(&self) -> Box<dyn Iterator<Item = Box<dyn ComponentInstance>>>;

    /// Iterate over the full set of descendants under this component in the component tree.
    fn descendants(&self) -> Box<dyn Iterator<Item = Box<dyn ComponentInstance>>>;

    /// Iterate over the full set of ancestors above this component in the component tree.
    fn ancestors(&self) -> Box<dyn Iterator<Item = Box<dyn ComponentInstance>>>;
}

// TODO(https://fxbug.dev/42063457): Define API compatible with moniker::Moniker.

/// Model of a component instance moniker, the instance's identifier in the context of
/// the component tree constructed by the underlying [`Scrutiny`] instance. See
/// https://fuchsia.dev/fuchsia-src/concepts/components/v2/identifiers#monikers for details.
pub trait Moniker {}

// TODO(https://fxbug.dev/42063457): Define API compatible with notion of bound environment in a component tree.

/// Model of a component instance environment that is realized in the context of the component
/// the component tree constructed by the underlying [`Scrutiny`] instance. See
/// https://fuchsia.dev/fuchsia-src/concepts/components/v2/environments for details.
pub trait Environment {}

#[cfg(test)]
mod tests {
    use super::super::data_source as ds;
    use super::ComponentResolverUrl;
    use super::DataSource;
    use super::DataSourceKind;
    use super::DataSourceVersion;
    use super::PackageResolverUrl;
    use super::Path;

    #[fuchsia::test]
    fn test_data_source_eq() {
        fn expect(a: Box<dyn DataSource>, b: Box<dyn DataSource>, eq: bool) {
            if eq {
                assert_eq!(&a, &b);
            } else {
                assert_ne!(&a, &b);
            }
        }

        fn new_data_source(
            kind: DataSourceKind,
            path: Option<Box<dyn Path>>,
            version: DataSourceVersion,
        ) -> ds::DataSource {
            ds::DataSource::new(ds::DataSourceInfo::new(kind, path, version))
        }

        fn reference_tree() -> ds::DataSource {
            let mut root = new_data_source(
                DataSourceKind::ProductBundle,
                Some(Box::new("/pb")),
                DataSourceVersion::Unknown,
            );

            let mut child_1 =
                new_data_source(DataSourceKind::TufRepository, None, DataSourceVersion::Unknown);
            root.add_child(child_1.clone());
            root.add_child(new_data_source(
                DataSourceKind::FvmVolume,
                Some(Box::new("/pb/fvm.blk")),
                DataSourceVersion::Unknown,
            ));
            child_1.add_child(new_data_source(
                DataSourceKind::BlobDirectory,
                Some(Box::new("/pb/test.fuchsia.com/blobs")),
                DataSourceVersion::Unknown,
            ));
            root
        }

        fn diff_child2_kind_tree() -> ds::DataSource {
            let mut root = new_data_source(
                DataSourceKind::ProductBundle,
                Some(Box::new("/pb")),
                DataSourceVersion::Unknown,
            );

            let mut child_1 =
                new_data_source(DataSourceKind::TufRepository, None, DataSourceVersion::Unknown);
            root.add_child(child_1.clone());
            root.add_child(new_data_source(
                // Divergence: FVM misclassified as blobfs volume.
                DataSourceKind::BlobfsArchive,
                Some(Box::new("/pb/fvm.blk")),
                DataSourceVersion::Unknown,
            ));
            child_1.add_child(new_data_source(
                DataSourceKind::BlobDirectory,
                Some(Box::new("/pb/test.fuchsia.com/blobs")),
                DataSourceVersion::Unknown,
            ));
            root
        }

        fn diff_repo_blobs_path_tree() -> ds::DataSource {
            let mut root = new_data_source(
                DataSourceKind::ProductBundle,
                Some(Box::new("/pb")),
                DataSourceVersion::Unknown,
            );

            let mut child_1 =
                new_data_source(DataSourceKind::TufRepository, None, DataSourceVersion::Unknown);
            root.add_child(child_1.clone());
            root.add_child(new_data_source(
                DataSourceKind::FvmVolume,
                Some(Box::new("/pb/fvm.blk")),
                DataSourceVersion::Unknown,
            ));
            child_1.add_child(new_data_source(
                DataSourceKind::BlobDirectory,
                // Divergence: Different path to repository blobs.
                Some(Box::new("/pb/test.fuchsia.com/test_blobs")),
                DataSourceVersion::Unknown,
            ));
            root
        }

        fn diff_missing_grandchild_tree() -> ds::DataSource {
            let mut root = new_data_source(
                DataSourceKind::ProductBundle,
                Some(Box::new("/pb")),
                DataSourceVersion::Unknown,
            );

            let child_1 =
                new_data_source(DataSourceKind::TufRepository, None, DataSourceVersion::Unknown);
            root.add_child(child_1.clone());
            root.add_child(new_data_source(
                DataSourceKind::FvmVolume,
                Some(Box::new("/pb/fvm.blk")),
                DataSourceVersion::Unknown,
            ));
            // Divergence: No grandchild under repository.
            root
        }

        fn diff_extra_root_tree() -> ds::DataSource {
            // Divergence: `reference_tree()` is a subtree under an additional root node.
            let mut extra_root =
                new_data_source(DataSourceKind::Unknown, None, DataSourceVersion::Unknown);
            let mut root = new_data_source(
                DataSourceKind::ProductBundle,
                Some(Box::new("/pb")),
                DataSourceVersion::Unknown,
            );
            extra_root.add_child(root.clone());

            let mut child_1 =
                new_data_source(DataSourceKind::TufRepository, None, DataSourceVersion::Unknown);
            root.add_child(child_1.clone());
            root.add_child(new_data_source(
                DataSourceKind::FvmVolume,
                Some(Box::new("/pb/fvm.blk")),
                DataSourceVersion::Unknown,
            ));
            child_1.add_child(new_data_source(
                DataSourceKind::BlobDirectory,
                Some(Box::new("/pb/test.fuchsia.com/blobs")),
                DataSourceVersion::Unknown,
            ));
            extra_root
        }

        fn diff_extra_descendant_tree() -> ds::DataSource {
            let mut root = new_data_source(
                DataSourceKind::ProductBundle,
                Some(Box::new("/pb")),
                DataSourceVersion::Unknown,
            );

            let mut child_1 =
                new_data_source(DataSourceKind::TufRepository, None, DataSourceVersion::Unknown);
            root.add_child(child_1.clone());
            root.add_child(new_data_source(
                DataSourceKind::FvmVolume,
                Some(Box::new("/pb/fvm.blk")),
                DataSourceVersion::Unknown,
            ));
            let mut grandchild_1 = new_data_source(
                DataSourceKind::BlobDirectory,
                Some(Box::new("/pb/test.fuchsia.com/blobs")),
                DataSourceVersion::Unknown,
            );
            child_1.add_child(grandchild_1.clone());
            // Divergence: `grandchild_1` has a child.
            grandchild_1.add_child(new_data_source(
                DataSourceKind::Unknown,
                None,
                DataSourceVersion::Unknown,
            ));
            root
        }

        expect(Box::new(reference_tree()), Box::new(reference_tree()), true);
        expect(Box::new(reference_tree()), Box::new(diff_child2_kind_tree()), false);
        expect(Box::new(reference_tree()), Box::new(diff_repo_blobs_path_tree()), false);
        expect(Box::new(reference_tree()), Box::new(diff_missing_grandchild_tree()), false);
        expect(Box::new(reference_tree()), Box::new(diff_extra_descendant_tree()), false);

        // The subtree rooted in the first (and only) child of `diff_extra_root_tree` is identical
        // to `reference_tree`, but should not be treated as equal due to the additional parent
        // above.
        let reference: Box<dyn DataSource> = Box::new(reference_tree());
        let extra_root = diff_extra_root_tree();
        let almost_same_as_reference = extra_root.children().next().expect("extra root has child");

        // Check that all node attributes are equal, but that the extra ancestor causes a deep
        // equality check to fail.
        assert_eq!(reference.kind(), almost_same_as_reference.kind());
        assert_eq!(reference.version(), almost_same_as_reference.version());
        assert_eq!(
            &reference.path().expect("root path"),
            &almost_same_as_reference.path().expect("extra root child path")
        );
        expect(reference, almost_same_as_reference, false);
    }

    #[fuchsia::test]
    fn test_parse_package_url() {
        PackageResolverUrl::parse("fuchsia-pkg://test.fuchsia.com/some_pkg")
            .expect("fully qualified package URL");
        PackageResolverUrl::parse("/some_pkg").expect("relative package URL");
        PackageResolverUrl::parse("fuchsia-boot:///some/pkg").expect("boot URL without resource");
        PackageResolverUrl::parse("fuchsia-pkg://test.fuchsia.com/some_pkg#meta/resource")
            .expect_err("package URL with resource");
        PackageResolverUrl::parse("fuchsia-boot:///some/pkg#meta/resource")
            .expect_err("boot URL with resource");
        PackageResolverUrl::parse("#meta/resource").expect_err("resource-only URL");
    }

    #[fuchsia::test]
    fn test_parse_component_url() {
        ComponentResolverUrl::parse("fuchsia-pkg://test.fuchsia.com/some_pkg")
            .expect_err("fully qualified package URL");
        ComponentResolverUrl::parse("/some_pkg").expect_err("relative package URL");
        ComponentResolverUrl::parse("fuchsia-boot:///some/pkg")
            .expect_err("boot URL without resource");
        ComponentResolverUrl::parse("fuchsia-pkg://test.fuchsia.com/some_pkg#meta/resource")
            .expect("package URL with resource");
        ComponentResolverUrl::parse("fuchsia-boot:///some/pkg#meta/resource")
            .expect("boot URL with resource");
        ComponentResolverUrl::parse("#meta/resource").expect("resource-only URL");
    }
}
