// Copyright 2021 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 anyhow::{Context, Error};
use assert_matches::assert_matches;
use cm_rust::{CapabilityTypeName, ComponentDecl, FidlIntoNative};
use cm_types::{LongName, Name, Path, RelativePath, Url};
use derivative::Derivative;
use std::collections::BTreeMap;
use {fidl_fuchsia_component_decl as fdecl, fidl_fuchsia_data as fdata, fidl_fuchsia_io as fio};

/// Name of the test runner.
///
/// Several functions assume the existence of a runner with this name.
pub const TEST_RUNNER_NAME: &str = "test_runner";

/// Deserialize `object` into a cml::Document and then translate the result
/// to ComponentDecl.
pub fn new_decl_from_json(object: serde_json::Value) -> Result<ComponentDecl, Error> {
    let doc = serde_json::from_value(object).context("failed to deserialize manifest")?;
    let cm =
        cml::compile(&doc, cml::CompileOptions::default()).context("failed to compile manifest")?;
    Ok(cm.fidl_into_native())
}

/// Builder for constructing a ComponentDecl.
#[derive(Debug, Clone)]
pub struct ComponentDeclBuilder {
    result: ComponentDecl,
}

impl ComponentDeclBuilder {
    /// An empty ComponentDeclBuilder, with no program.
    pub fn new_empty_component() -> Self {
        ComponentDeclBuilder { result: Default::default() }
    }

    /// A ComponentDeclBuilder prefilled with a program and using a runner named "test_runner",
    /// which we assume is offered to us.
    pub fn new() -> Self {
        Self::new_empty_component().program_runner(TEST_RUNNER_NAME)
    }

    /// Add a child element.
    pub fn child(mut self, decl: impl Into<cm_rust::ChildDecl>) -> Self {
        self.result.children.push(decl.into());
        self
    }

    /// Add a child with default properties.
    pub fn child_default(self, name: &str) -> Self {
        self.child(ChildBuilder::new().name(name))
    }

    // Add a collection element.
    pub fn collection(mut self, decl: impl Into<cm_rust::CollectionDecl>) -> Self {
        self.result.collections.push(decl.into());
        self
    }

    /// Add a collection with default properties.
    pub fn collection_default(self, name: &str) -> Self {
        self.collection(CollectionBuilder::new().name(name))
    }

    /// Add a "program" clause, using the given runner.
    pub fn program_runner(self, runner: &str) -> Self {
        assert!(self.result.program.is_none(), "tried to add program twice");
        self.program(cm_rust::ProgramDecl {
            runner: Some(runner.parse().unwrap()),
            info: fdata::Dictionary { entries: Some(vec![]), ..Default::default() },
        })
    }

    pub fn program(mut self, program: cm_rust::ProgramDecl) -> Self {
        self.result.program = Some(program);
        self
    }

    /// Add an offer decl.
    pub fn offer(mut self, offer: impl Into<cm_rust::OfferDecl>) -> Self {
        self.result.offers.push(offer.into());
        self
    }

    /// Add an expose decl.
    pub fn expose(mut self, expose: impl Into<cm_rust::ExposeDecl>) -> Self {
        self.result.exposes.push(expose.into());
        self
    }

    /// Add a use decl.
    pub fn use_(mut self, use_: impl Into<cm_rust::UseDecl>) -> Self {
        self.result.uses.push(use_.into());
        self
    }

    // Add a use decl for fuchsia.component.Realm.
    pub fn use_realm(self) -> Self {
        self.use_(
            UseBuilder::protocol()
                .name("fuchsia.component.Realm")
                .source(cm_rust::UseSource::Framework),
        )
    }

    /// Add a capability declaration.
    pub fn capability(mut self, capability: impl Into<cm_rust::CapabilityDecl>) -> Self {
        self.result.capabilities.push(capability.into());
        self
    }

    /// Add a default protocol declaration.
    pub fn protocol_default(self, name: &str) -> Self {
        self.capability(CapabilityBuilder::protocol().name(name))
    }

    /// Add a default dictionary declaration.
    pub fn dictionary_default(self, name: &str) -> Self {
        self.capability(CapabilityBuilder::dictionary().name(name))
    }

    /// Add a default runner declaration.
    pub fn runner_default(self, name: &str) -> Self {
        self.capability(CapabilityBuilder::runner().name(name))
    }

    /// Add a default resolver declaration.
    pub fn resolver_default(self, name: &str) -> Self {
        self.capability(CapabilityBuilder::resolver().name(name))
    }

    /// Add a default service declaration.
    pub fn service_default(self, name: &str) -> Self {
        self.capability(CapabilityBuilder::service().name(name))
    }

    /// Add an environment declaration.
    pub fn environment(mut self, environment: impl Into<cm_rust::EnvironmentDecl>) -> Self {
        self.result.environments.push(environment.into());
        self
    }

    /// Add a config declaration.
    pub fn config(mut self, config: cm_rust::ConfigDecl) -> Self {
        self.result.config = Some(config);
        self
    }

    /// Generate the final ComponentDecl.
    pub fn build(self) -> ComponentDecl {
        self.result
    }
}

/// A convenience builder for constructing ChildDecls.
#[derive(Debug, Derivative)]
#[derivative(Default)]
pub struct ChildBuilder {
    name: Option<LongName>,
    url: Option<Url>,
    #[derivative(Default(value = "fdecl::StartupMode::Lazy"))]
    startup: fdecl::StartupMode,
    on_terminate: Option<fdecl::OnTerminate>,
    environment: Option<Name>,
}

impl ChildBuilder {
    pub fn new() -> Self {
        Self::default()
    }

    /// Defaults url to `"test:///{name}"`.
    pub fn name(mut self, name: &str) -> Self {
        self.name = Some(name.parse().unwrap());
        if self.url.is_none() {
            self.url = Some(format!("test:///{name}").parse().unwrap());
        }
        self
    }

    pub fn url(mut self, url: &str) -> Self {
        self.url = Some(url.parse().unwrap());
        self
    }

    pub fn startup(mut self, startup: fdecl::StartupMode) -> Self {
        self.startup = startup;
        self
    }

    pub fn eager(self) -> Self {
        self.startup(fdecl::StartupMode::Eager)
    }

    pub fn on_terminate(mut self, on_terminate: fdecl::OnTerminate) -> Self {
        self.on_terminate = Some(on_terminate);
        self
    }

    pub fn environment(mut self, environment: &str) -> Self {
        self.environment = Some(environment.parse().unwrap());
        self
    }

    pub fn build(self) -> cm_rust::ChildDecl {
        cm_rust::ChildDecl {
            name: self.name.expect("name not set"),
            url: self.url.expect("url not set"),
            startup: self.startup,
            on_terminate: self.on_terminate,
            environment: self.environment,
            config_overrides: None,
        }
    }
}

impl From<ChildBuilder> for cm_rust::ChildDecl {
    fn from(builder: ChildBuilder) -> Self {
        builder.build()
    }
}

/// A convenience builder for constructing CollectionDecls.
#[derive(Debug, Derivative)]
#[derivative(Default)]
pub struct CollectionBuilder {
    name: Option<Name>,
    #[derivative(Default(value = "fdecl::Durability::Transient"))]
    durability: fdecl::Durability,
    environment: Option<Name>,
    #[derivative(Default(value = "cm_types::AllowedOffers::StaticOnly"))]
    allowed_offers: cm_types::AllowedOffers,
    allow_long_names: bool,
    persistent_storage: Option<bool>,
}

impl CollectionBuilder {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn name(mut self, name: &str) -> Self {
        self.name = Some(name.parse().unwrap());
        self
    }

    pub fn durability(mut self, durability: fdecl::Durability) -> Self {
        self.durability = durability;
        self
    }

    pub fn environment(mut self, environment: &str) -> Self {
        self.environment = Some(environment.parse().unwrap());
        self
    }

    pub fn allowed_offers(mut self, allowed_offers: cm_types::AllowedOffers) -> Self {
        self.allowed_offers = allowed_offers;
        self
    }

    pub fn allow_long_names(mut self) -> Self {
        self.allow_long_names = true;
        self
    }

    pub fn persistent_storage(mut self, persistent_storage: bool) -> Self {
        self.persistent_storage = Some(persistent_storage);
        self
    }

    pub fn build(self) -> cm_rust::CollectionDecl {
        cm_rust::CollectionDecl {
            name: self.name.expect("name not set"),
            durability: self.durability,
            environment: self.environment,
            allowed_offers: self.allowed_offers,
            allow_long_names: self.allow_long_names,
            persistent_storage: self.persistent_storage,
        }
    }
}

impl From<CollectionBuilder> for cm_rust::CollectionDecl {
    fn from(builder: CollectionBuilder) -> Self {
        builder.build()
    }
}

/// A convenience builder for constructing EnvironmentDecls.
#[derive(Debug, Derivative)]
#[derivative(Default)]
pub struct EnvironmentBuilder {
    name: Option<Name>,
    #[derivative(Default(value = "fdecl::EnvironmentExtends::Realm"))]
    extends: fdecl::EnvironmentExtends,
    runners: Vec<cm_rust::RunnerRegistration>,
    resolvers: Vec<cm_rust::ResolverRegistration>,
    debug_capabilities: Vec<cm_rust::DebugRegistration>,
    stop_timeout_ms: Option<u32>,
}

impl EnvironmentBuilder {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn name(mut self, name: &str) -> Self {
        self.name = Some(name.parse().unwrap());
        self
    }

    pub fn extends(mut self, extends: fdecl::EnvironmentExtends) -> Self {
        self.extends = extends;
        self
    }

    pub fn runner(mut self, runner: cm_rust::RunnerRegistration) -> Self {
        self.runners.push(runner);
        self
    }

    pub fn resolver(mut self, resolver: cm_rust::ResolverRegistration) -> Self {
        self.resolvers.push(resolver);
        self
    }

    pub fn debug(mut self, debug: cm_rust::DebugRegistration) -> Self {
        self.debug_capabilities.push(debug);
        self
    }

    pub fn stop_timeout(mut self, timeout_ms: u32) -> Self {
        self.stop_timeout_ms = Some(timeout_ms);
        self
    }

    pub fn build(self) -> cm_rust::EnvironmentDecl {
        cm_rust::EnvironmentDecl {
            name: self.name.expect("name not set"),
            extends: self.extends,
            runners: self.runners,
            resolvers: self.resolvers,
            debug_capabilities: self.debug_capabilities,
            stop_timeout_ms: self.stop_timeout_ms,
        }
    }
}

impl From<EnvironmentBuilder> for cm_rust::EnvironmentDecl {
    fn from(builder: EnvironmentBuilder) -> Self {
        builder.build()
    }
}

/// A convenience builder for constructing [CapabilityDecl]s.
///
/// To use, call the constructor matching their capability type ([CapabilityBuilder::protocol],
/// [CapabilityBuilder::directory], etc., and then call methods to set properties. When done,
/// call [CapabilityBuilder::build] (or [Into::into]) to generate the [CapabilityDecl].
#[derive(Debug)]
pub struct CapabilityBuilder {
    name: Option<Name>,
    type_: CapabilityTypeName,
    path: Option<Path>,
    dictionary_source: Option<cm_rust::DictionarySource>,
    source_dictionary: Option<RelativePath>,
    rights: fio::Operations,
    subdir: RelativePath,
    backing_dir: Option<Name>,
    storage_source: Option<cm_rust::StorageDirectorySource>,
    storage_id: fdecl::StorageId,
    value: Option<cm_rust::ConfigValue>,
    delivery: cm_rust::DeliveryType,
}

impl CapabilityBuilder {
    pub fn protocol() -> Self {
        Self::new(CapabilityTypeName::Protocol)
    }

    pub fn service() -> Self {
        Self::new(CapabilityTypeName::Service)
    }

    pub fn directory() -> Self {
        Self::new(CapabilityTypeName::Directory)
    }

    pub fn storage() -> Self {
        Self::new(CapabilityTypeName::Storage)
    }

    pub fn runner() -> Self {
        Self::new(CapabilityTypeName::Runner)
    }

    pub fn resolver() -> Self {
        Self::new(CapabilityTypeName::Resolver)
    }

    pub fn dictionary() -> Self {
        Self::new(CapabilityTypeName::Dictionary)
    }

    pub fn config() -> Self {
        Self::new(CapabilityTypeName::Config)
    }

    pub fn name(mut self, name: &str) -> Self {
        self.name = Some(name.parse().unwrap());
        if self.path.is_some() {
            return self;
        }
        match self.type_ {
            CapabilityTypeName::Protocol => {
                self.path = Some(format!("/svc/{name}").parse().unwrap());
            }
            CapabilityTypeName::Service => {
                self.path = Some(format!("/svc/{name}").parse().unwrap());
            }
            CapabilityTypeName::Runner => {
                self.path = Some("/svc/fuchsia.component.runner.ComponentRunner".parse().unwrap());
            }
            CapabilityTypeName::Resolver => {
                self.path = Some("/svc/fuchsia.component.resolution.Resolver".parse().unwrap());
            }
            CapabilityTypeName::Dictionary
            | CapabilityTypeName::Storage
            | CapabilityTypeName::Config
            | CapabilityTypeName::Directory => {}
            CapabilityTypeName::EventStream => unreachable!(),
        }
        self
    }

    fn new(type_: CapabilityTypeName) -> Self {
        Self {
            type_,
            name: None,
            path: None,
            dictionary_source: None,
            source_dictionary: None,
            rights: fio::R_STAR_DIR,
            subdir: Default::default(),
            backing_dir: None,
            storage_source: None,
            storage_id: fdecl::StorageId::StaticInstanceIdOrMoniker,
            value: None,
            delivery: Default::default(),
        }
    }

    pub fn path(mut self, path: &str) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Service
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Runner
                | CapabilityTypeName::Resolver
        );
        self.path = Some(path.parse().unwrap());
        self
    }

    pub fn rights(mut self, rights: fio::Operations) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.rights = rights;
        self
    }

    pub fn source_dictionary(
        mut self,
        source: cm_rust::DictionarySource,
        source_dictionary: &str,
    ) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Dictionary);
        self.dictionary_source = Some(source);
        self.source_dictionary = Some(source_dictionary.parse().unwrap());
        self
    }

    pub fn backing_dir(mut self, backing_dir: &str) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Storage);
        self.backing_dir = Some(backing_dir.parse().unwrap());
        self
    }

    pub fn value(mut self, value: cm_rust::ConfigValue) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Config);
        self.value = Some(value);
        self
    }

    pub fn source(mut self, source: cm_rust::StorageDirectorySource) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Storage);
        self.storage_source = Some(source);
        self
    }

    pub fn subdir(mut self, subdir: &str) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Storage);
        self.subdir = subdir.parse().unwrap();
        self
    }

    pub fn storage_id(mut self, storage_id: fdecl::StorageId) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Storage);
        self.storage_id = storage_id;
        self
    }

    pub fn delivery(mut self, delivery: cm_rust::DeliveryType) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Protocol);
        self.delivery = delivery;
        self
    }

    pub fn build(self) -> cm_rust::CapabilityDecl {
        match self.type_ {
            CapabilityTypeName::Protocol => {
                cm_rust::CapabilityDecl::Protocol(cm_rust::ProtocolDecl {
                    name: self.name.expect("name not set"),
                    source_path: Some(self.path.expect("path not set")),
                    delivery: self.delivery,
                })
            }
            CapabilityTypeName::Service => cm_rust::CapabilityDecl::Service(cm_rust::ServiceDecl {
                name: self.name.expect("name not set"),
                source_path: Some(self.path.expect("path not set")),
            }),
            CapabilityTypeName::Runner => cm_rust::CapabilityDecl::Runner(cm_rust::RunnerDecl {
                name: self.name.expect("name not set"),
                source_path: Some(self.path.expect("path not set")),
            }),
            CapabilityTypeName::Resolver => {
                cm_rust::CapabilityDecl::Resolver(cm_rust::ResolverDecl {
                    name: self.name.expect("name not set"),
                    source_path: Some(self.path.expect("path not set")),
                })
            }
            CapabilityTypeName::Dictionary => {
                cm_rust::CapabilityDecl::Dictionary(cm_rust::DictionaryDecl {
                    name: self.name.expect("name not set"),
                    source: self.dictionary_source,
                    source_dictionary: self.source_dictionary,
                })
            }
            CapabilityTypeName::Storage => cm_rust::CapabilityDecl::Storage(cm_rust::StorageDecl {
                name: self.name.expect("name not set"),
                backing_dir: self.backing_dir.expect("backing_dir not set"),
                source: self.storage_source.expect("source not set"),
                subdir: self.subdir,
                storage_id: self.storage_id,
            }),
            CapabilityTypeName::Directory => {
                cm_rust::CapabilityDecl::Directory(cm_rust::DirectoryDecl {
                    name: self.name.expect("name not set"),
                    source_path: Some(self.path.expect("path not set")),
                    rights: self.rights,
                })
            }
            CapabilityTypeName::Config => {
                cm_rust::CapabilityDecl::Config(cm_rust::ConfigurationDecl {
                    name: self.name.expect("name not set"),
                    value: self.value.expect("value not set"),
                })
            }
            CapabilityTypeName::EventStream => unreachable!(),
        }
    }
}

impl From<CapabilityBuilder> for cm_rust::CapabilityDecl {
    fn from(builder: CapabilityBuilder) -> Self {
        builder.build()
    }
}

/// A convenience builder for constructing [UseDecl]s.
///
/// To use, call the constructor matching their capability type ([UseBuilder::protocol],
/// [UseBuilder::directory], etc.), and then call methods to set properties. When done,
/// call [UseBuilder::build] (or [Into::into]) to generate the [UseDecl].
#[derive(Debug)]
pub struct UseBuilder {
    source_name: Option<Name>,
    type_: CapabilityTypeName,
    source_dictionary: RelativePath,
    source: cm_rust::UseSource,
    target_name: Option<Name>,
    target_path: Option<Path>,
    dependency_type: cm_rust::DependencyType,
    availability: cm_rust::Availability,
    rights: fio::Operations,
    subdir: RelativePath,
    scope: Option<Vec<cm_rust::EventScope>>,
    filter: Option<BTreeMap<String, cm_rust::DictionaryValue>>,
    config_type: Option<cm_rust::ConfigValueType>,
}

impl UseBuilder {
    pub fn protocol() -> Self {
        Self::new(CapabilityTypeName::Protocol)
    }

    pub fn service() -> Self {
        Self::new(CapabilityTypeName::Service)
    }

    pub fn directory() -> Self {
        Self::new(CapabilityTypeName::Directory)
    }

    pub fn storage() -> Self {
        Self::new(CapabilityTypeName::Storage)
    }

    pub fn runner() -> Self {
        Self::new(CapabilityTypeName::Runner)
    }

    pub fn event_stream() -> Self {
        Self::new(CapabilityTypeName::EventStream)
    }

    pub fn config() -> Self {
        Self::new(CapabilityTypeName::Config)
    }

    fn new(type_: CapabilityTypeName) -> Self {
        Self {
            type_,
            source: cm_rust::UseSource::Parent,
            source_name: None,
            target_name: None,
            target_path: None,
            source_dictionary: Default::default(),
            rights: fio::R_STAR_DIR,
            subdir: Default::default(),
            dependency_type: cm_rust::DependencyType::Strong,
            availability: cm_rust::Availability::Required,
            scope: None,
            filter: None,
            config_type: None,
        }
    }

    pub fn config_type(mut self, type_: cm_rust::ConfigValueType) -> Self {
        self.config_type = Some(type_);
        self
    }

    pub fn name(mut self, name: &str) -> Self {
        self.source_name = Some(name.parse().unwrap());
        if self.target_path.is_some() || self.target_name.is_some() {
            return self;
        }
        match self.type_ {
            CapabilityTypeName::Protocol | CapabilityTypeName::Service => {
                self.target_path = Some(format!("/svc/{name}").parse().unwrap());
            }
            CapabilityTypeName::EventStream => {
                self.target_path = Some("/svc/fuchsia.component.EventStream".parse().unwrap());
            }
            CapabilityTypeName::Runner | CapabilityTypeName::Config => {
                self.target_name = self.source_name.clone();
            }
            CapabilityTypeName::Storage | CapabilityTypeName::Directory => {}
            CapabilityTypeName::Dictionary | CapabilityTypeName::Resolver => unreachable!(),
        }
        self
    }

    pub fn path(mut self, path: &str) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Service
                | CapabilityTypeName::Directory
                | CapabilityTypeName::EventStream
                | CapabilityTypeName::Storage
        );
        self.target_path = Some(path.parse().unwrap());
        self
    }

    pub fn target_name(mut self, name: &str) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Runner | CapabilityTypeName::Config);
        self.target_name = Some(name.parse().unwrap());
        self
    }

    pub fn from_dictionary(mut self, dictionary: &str) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Service
                | CapabilityTypeName::Protocol
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Runner
        );
        self.source_dictionary = dictionary.parse().unwrap();
        self
    }

    pub fn source(mut self, source: cm_rust::UseSource) -> Self {
        assert_matches!(self.type_, t if t != CapabilityTypeName::Storage);
        self.source = source;
        self
    }

    pub fn source_static_child(self, source: &str) -> Self {
        self.source(cm_rust::UseSource::Child(source.parse().unwrap()))
    }

    pub fn availability(mut self, availability: cm_rust::Availability) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Service
                | CapabilityTypeName::Directory
                | CapabilityTypeName::EventStream
                | CapabilityTypeName::Storage
                | CapabilityTypeName::Config
        );
        self.availability = availability;
        self
    }

    pub fn dependency(mut self, dependency: cm_rust::DependencyType) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Service
                | CapabilityTypeName::Directory
        );
        self.dependency_type = dependency;
        self
    }

    pub fn rights(mut self, rights: fio::Operations) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.rights = rights;
        self
    }

    pub fn subdir(mut self, subdir: &str) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.subdir = subdir.parse().unwrap();
        self
    }

    pub fn scope(mut self, scope: Vec<cm_rust::EventScope>) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::EventStream);
        self.scope = Some(scope);
        self
    }

    pub fn filter(mut self, filter: BTreeMap<String, cm_rust::DictionaryValue>) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::EventStream);
        self.filter = Some(filter);
        self
    }

    pub fn build(self) -> cm_rust::UseDecl {
        match self.type_ {
            CapabilityTypeName::Protocol => cm_rust::UseDecl::Protocol(cm_rust::UseProtocolDecl {
                source: self.source,
                source_name: self.source_name.expect("name not set"),
                source_dictionary: self.source_dictionary,
                target_path: self.target_path.expect("path not set"),
                dependency_type: self.dependency_type,
                availability: self.availability,
            }),
            CapabilityTypeName::Service => cm_rust::UseDecl::Service(cm_rust::UseServiceDecl {
                source: self.source,
                source_name: self.source_name.expect("name not set"),
                source_dictionary: self.source_dictionary,
                target_path: self.target_path.expect("path not set"),
                dependency_type: self.dependency_type,
                availability: self.availability,
            }),
            CapabilityTypeName::Directory => {
                cm_rust::UseDecl::Directory(cm_rust::UseDirectoryDecl {
                    source: self.source,
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target_path: self.target_path.expect("path not set"),
                    rights: self.rights,
                    subdir: self.subdir,
                    dependency_type: self.dependency_type,
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Storage => cm_rust::UseDecl::Storage(cm_rust::UseStorageDecl {
                source_name: self.source_name.expect("name not set"),
                target_path: self.target_path.expect("path not set"),
                availability: self.availability,
            }),
            CapabilityTypeName::EventStream => {
                cm_rust::UseDecl::EventStream(cm_rust::UseEventStreamDecl {
                    source: self.source,
                    source_name: self.source_name.expect("name not set"),
                    target_path: self.target_path.expect("path not set"),
                    availability: self.availability,
                    scope: self.scope,
                    filter: self.filter,
                })
            }
            CapabilityTypeName::Runner => cm_rust::UseDecl::Runner(cm_rust::UseRunnerDecl {
                source: self.source,
                source_name: self.source_name.expect("name not set"),
                source_dictionary: self.source_dictionary,
            }),
            CapabilityTypeName::Config => cm_rust::UseDecl::Config(cm_rust::UseConfigurationDecl {
                source: self.source,
                source_name: self.source_name.expect("name not set"),
                target_name: self.target_name.expect("target name not set"),
                availability: self.availability,
                type_: self.config_type.expect("config_type not set"),
                default: None,
            }),
            CapabilityTypeName::Resolver | CapabilityTypeName::Dictionary => unreachable!(),
        }
    }
}

impl From<UseBuilder> for cm_rust::UseDecl {
    fn from(builder: UseBuilder) -> Self {
        builder.build()
    }
}

/// A convenience builder for constructing [ExposeDecl]s.
///
/// To use, call the constructor matching their capability type ([ExposeBuilder::protocol],
/// [ExposeBuilder::directory], etc.), and then call methods to set properties. When done,
/// call [ExposeBuilder::build] (or [Into::into]) to generate the [ExposeDecl].
#[derive(Debug)]
pub struct ExposeBuilder {
    source_name: Option<Name>,
    type_: CapabilityTypeName,
    source_dictionary: RelativePath,
    source: Option<cm_rust::ExposeSource>,
    target: cm_rust::ExposeTarget,
    target_name: Option<Name>,
    availability: cm_rust::Availability,
    rights: Option<fio::Operations>,
    subdir: RelativePath,
}

impl ExposeBuilder {
    pub fn protocol() -> Self {
        Self::new(CapabilityTypeName::Protocol)
    }

    pub fn service() -> Self {
        Self::new(CapabilityTypeName::Service)
    }

    pub fn directory() -> Self {
        Self::new(CapabilityTypeName::Directory)
    }

    pub fn runner() -> Self {
        Self::new(CapabilityTypeName::Runner)
    }

    pub fn resolver() -> Self {
        Self::new(CapabilityTypeName::Resolver)
    }

    pub fn dictionary() -> Self {
        Self::new(CapabilityTypeName::Dictionary)
    }

    pub fn config() -> Self {
        Self::new(CapabilityTypeName::Config)
    }

    fn new(type_: CapabilityTypeName) -> Self {
        Self {
            type_,
            source: None,
            target: cm_rust::ExposeTarget::Parent,
            source_name: None,
            target_name: None,
            source_dictionary: Default::default(),
            rights: None,
            subdir: Default::default(),
            availability: cm_rust::Availability::Required,
        }
    }

    pub fn name(mut self, name: &str) -> Self {
        self.source_name = Some(name.parse().unwrap());
        if self.target_name.is_some() {
            return self;
        }
        self.target_name = self.source_name.clone();
        self
    }

    pub fn target_name(mut self, name: &str) -> Self {
        self.target_name = Some(name.parse().unwrap());
        self
    }

    pub fn from_dictionary(mut self, dictionary: &str) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Service
                | CapabilityTypeName::Protocol
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Dictionary
                | CapabilityTypeName::Runner
                | CapabilityTypeName::Resolver
        );
        self.source_dictionary = dictionary.parse().unwrap();
        self
    }

    pub fn source(mut self, source: cm_rust::ExposeSource) -> Self {
        self.source = Some(source);
        self
    }

    pub fn source_static_child(self, source: &str) -> Self {
        self.source(cm_rust::ExposeSource::Child(source.parse().unwrap()))
    }

    pub fn target(mut self, target: cm_rust::ExposeTarget) -> Self {
        self.target = target;
        self
    }

    pub fn availability(mut self, availability: cm_rust::Availability) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Service
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Config
                | CapabilityTypeName::Dictionary
        );
        self.availability = availability;
        self
    }

    pub fn rights(mut self, rights: fio::Operations) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.rights = Some(rights);
        self
    }

    pub fn subdir(mut self, subdir: &str) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.subdir = subdir.parse().unwrap();
        self
    }

    pub fn build(self) -> cm_rust::ExposeDecl {
        match self.type_ {
            CapabilityTypeName::Protocol => {
                cm_rust::ExposeDecl::Protocol(cm_rust::ExposeProtocolDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target,
                    target_name: self.target_name.expect("name not set"),
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Service => {
                cm_rust::ExposeDecl::Service(cm_rust::ExposeServiceDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target,
                    target_name: self.target_name.expect("name not set"),
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Directory => {
                cm_rust::ExposeDecl::Directory(cm_rust::ExposeDirectoryDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target,
                    target_name: self.target_name.expect("name not set"),
                    rights: self.rights,
                    subdir: self.subdir,
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Runner => cm_rust::ExposeDecl::Runner(cm_rust::ExposeRunnerDecl {
                source: self.source.expect("source not set"),
                source_name: self.source_name.expect("name not set"),
                source_dictionary: self.source_dictionary,
                target: self.target,
                target_name: self.target_name.expect("name not set"),
            }),
            CapabilityTypeName::Resolver => {
                cm_rust::ExposeDecl::Resolver(cm_rust::ExposeResolverDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target,
                    target_name: self.target_name.expect("name not set"),
                })
            }
            CapabilityTypeName::Config => {
                cm_rust::ExposeDecl::Config(cm_rust::ExposeConfigurationDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    target: self.target,
                    target_name: self.target_name.expect("name not set"),
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Dictionary => {
                cm_rust::ExposeDecl::Dictionary(cm_rust::ExposeDictionaryDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target,
                    target_name: self.target_name.expect("name not set"),
                    availability: self.availability,
                })
            }
            CapabilityTypeName::EventStream | CapabilityTypeName::Storage => unreachable!(),
        }
    }
}

impl From<ExposeBuilder> for cm_rust::ExposeDecl {
    fn from(builder: ExposeBuilder) -> Self {
        builder.build()
    }
}

pub fn offer_source_static_child(name: &str) -> cm_rust::OfferSource {
    cm_rust::OfferSource::Child(cm_rust::ChildRef { name: name.parse().unwrap(), collection: None })
}

pub fn offer_target_static_child(name: &str) -> cm_rust::OfferTarget {
    cm_rust::OfferTarget::Child(cm_rust::ChildRef { name: name.parse().unwrap(), collection: None })
}

/// A convenience builder for constructing [OfferDecl]s.
///
/// To use, call the constructor matching their capability type ([OfferBuilder::protocol],
/// [OfferBuilder::directory], etc.), and then call methods to set properties. When done,
/// call [OfferBuilder::build] (or [Into::into]) to generate the [OfferDecl].
#[derive(Debug)]
pub struct OfferBuilder {
    source_name: Option<Name>,
    type_: CapabilityTypeName,
    source_dictionary: RelativePath,
    source: Option<cm_rust::OfferSource>,
    target: Option<cm_rust::OfferTarget>,
    target_name: Option<Name>,
    source_instance_filter: Option<Vec<Name>>,
    renamed_instances: Option<Vec<cm_rust::NameMapping>>,
    rights: Option<fio::Operations>,
    subdir: RelativePath,
    scope: Option<Vec<cm_rust::EventScope>>,
    dependency_type: cm_rust::DependencyType,
    availability: cm_rust::Availability,
}

impl OfferBuilder {
    pub fn protocol() -> Self {
        Self::new(CapabilityTypeName::Protocol)
    }

    pub fn service() -> Self {
        Self::new(CapabilityTypeName::Service)
    }

    pub fn directory() -> Self {
        Self::new(CapabilityTypeName::Directory)
    }

    pub fn storage() -> Self {
        Self::new(CapabilityTypeName::Storage)
    }

    pub fn runner() -> Self {
        Self::new(CapabilityTypeName::Runner)
    }

    pub fn resolver() -> Self {
        Self::new(CapabilityTypeName::Resolver)
    }

    pub fn dictionary() -> Self {
        Self::new(CapabilityTypeName::Dictionary)
    }

    pub fn event_stream() -> Self {
        Self::new(CapabilityTypeName::EventStream)
    }

    pub fn config() -> Self {
        Self::new(CapabilityTypeName::Config)
    }

    fn new(type_: CapabilityTypeName) -> Self {
        Self {
            type_,
            source: None,
            target: None,
            source_name: None,
            target_name: None,
            source_dictionary: Default::default(),
            source_instance_filter: None,
            renamed_instances: None,
            rights: None,
            subdir: Default::default(),
            scope: None,
            dependency_type: cm_rust::DependencyType::Strong,
            availability: cm_rust::Availability::Required,
        }
    }

    pub fn name(mut self, name: &str) -> Self {
        self.source_name = Some(name.parse().unwrap());
        if self.target_name.is_some() {
            return self;
        }
        self.target_name = self.source_name.clone();
        self
    }

    pub fn target_name(mut self, name: &str) -> Self {
        self.target_name = Some(name.parse().unwrap());
        self
    }

    pub fn from_dictionary(mut self, dictionary: &str) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Service
                | CapabilityTypeName::Protocol
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Dictionary
                | CapabilityTypeName::Runner
                | CapabilityTypeName::Resolver
        );
        self.source_dictionary = dictionary.parse().unwrap();
        self
    }

    pub fn source(mut self, source: cm_rust::OfferSource) -> Self {
        self.source = Some(source);
        self
    }

    pub fn source_static_child(self, source: &str) -> Self {
        self.source(offer_source_static_child(source))
    }

    pub fn target(mut self, target: cm_rust::OfferTarget) -> Self {
        self.target = Some(target);
        self
    }

    pub fn target_static_child(self, target: &str) -> Self {
        self.target(offer_target_static_child(target))
    }

    pub fn availability(mut self, availability: cm_rust::Availability) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Service
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Storage
                | CapabilityTypeName::EventStream
                | CapabilityTypeName::Config
                | CapabilityTypeName::Dictionary
        );
        self.availability = availability;
        self
    }

    pub fn dependency(mut self, dependency: cm_rust::DependencyType) -> Self {
        assert_matches!(
            self.type_,
            CapabilityTypeName::Protocol
                | CapabilityTypeName::Directory
                | CapabilityTypeName::Dictionary
        );
        self.dependency_type = dependency;
        self
    }

    pub fn source_instance_filter<'a>(mut self, filter: impl IntoIterator<Item = &'a str>) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Service);
        self.source_instance_filter =
            Some(filter.into_iter().map(|s| s.parse().unwrap()).collect());
        self
    }

    pub fn renamed_instances<'a, 'b>(
        mut self,
        mapping: impl IntoIterator<Item = (&'a str, &'b str)>,
    ) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Service);
        self.renamed_instances = Some(
            mapping
                .into_iter()
                .map(|(s, t)| cm_rust::NameMapping {
                    source_name: s.parse().unwrap(),
                    target_name: t.parse().unwrap(),
                })
                .collect(),
        );
        self
    }

    pub fn rights(mut self, rights: fio::Operations) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.rights = Some(rights);
        self
    }

    pub fn subdir(mut self, subdir: &str) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::Directory);
        self.subdir = subdir.parse().unwrap();
        self
    }

    pub fn scope(mut self, scope: Vec<cm_rust::EventScope>) -> Self {
        assert_matches!(self.type_, CapabilityTypeName::EventStream);
        self.scope = Some(scope);
        self
    }

    pub fn build(self) -> cm_rust::OfferDecl {
        match self.type_ {
            CapabilityTypeName::Protocol => {
                cm_rust::OfferDecl::Protocol(cm_rust::OfferProtocolDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target.expect("target not set"),
                    target_name: self.target_name.expect("name not set"),
                    dependency_type: self.dependency_type,
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Service => cm_rust::OfferDecl::Service(cm_rust::OfferServiceDecl {
                source: self.source.expect("source not set"),
                source_name: self.source_name.expect("name not set"),
                source_dictionary: self.source_dictionary,
                target: self.target.expect("target is not set"),
                target_name: self.target_name.expect("name not set"),
                source_instance_filter: self.source_instance_filter,
                renamed_instances: self.renamed_instances,
                availability: self.availability,
            }),
            CapabilityTypeName::Directory => {
                cm_rust::OfferDecl::Directory(cm_rust::OfferDirectoryDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target.expect("target is not set"),
                    target_name: self.target_name.expect("name not set"),
                    rights: self.rights,
                    subdir: self.subdir,
                    dependency_type: self.dependency_type,
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Storage => cm_rust::OfferDecl::Storage(cm_rust::OfferStorageDecl {
                source: self.source.expect("source not set"),
                source_name: self.source_name.expect("name not set"),
                target: self.target.expect("target is not set"),
                target_name: self.target_name.expect("name not set"),
                availability: self.availability,
            }),
            CapabilityTypeName::EventStream => {
                cm_rust::OfferDecl::EventStream(cm_rust::OfferEventStreamDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    target: self.target.expect("target is not set"),
                    target_name: self.target_name.expect("name not set"),
                    availability: self.availability,
                    scope: self.scope,
                })
            }
            CapabilityTypeName::Runner => cm_rust::OfferDecl::Runner(cm_rust::OfferRunnerDecl {
                source: self.source.expect("source not set"),
                source_name: self.source_name.expect("name not set"),
                source_dictionary: self.source_dictionary,
                target: self.target.expect("target is not set"),
                target_name: self.target_name.expect("name not set"),
            }),
            CapabilityTypeName::Resolver => {
                cm_rust::OfferDecl::Resolver(cm_rust::OfferResolverDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target.expect("target is not set"),
                    target_name: self.target_name.expect("name not set"),
                })
            }
            CapabilityTypeName::Config => {
                cm_rust::OfferDecl::Config(cm_rust::OfferConfigurationDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    target: self.target.expect("target not set"),
                    target_name: self.target_name.expect("name not set"),
                    availability: self.availability,
                })
            }
            CapabilityTypeName::Dictionary => {
                cm_rust::OfferDecl::Dictionary(cm_rust::OfferDictionaryDecl {
                    source: self.source.expect("source not set"),
                    source_name: self.source_name.expect("name not set"),
                    source_dictionary: self.source_dictionary,
                    target: self.target.expect("target not set"),
                    target_name: self.target_name.expect("name not set"),
                    dependency_type: self.dependency_type,
                    availability: self.availability,
                })
            }
        }
    }
}

impl From<OfferBuilder> for cm_rust::OfferDecl {
    fn from(builder: OfferBuilder) -> Self {
        builder.build()
    }
}
