// 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 anyhow::Error;
use fidl::encoding::decode_persistent;
use fidl_fuchsia_data as fdata;
use fidl_fuchsia_io2 as fio2;
use fidl_fuchsia_sys2::*;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

fn main() {
    // example.cm has already been compiled by cmc as part of the build process
    // See: https://fuchsia.googlesource.com/fuchsia/+/c4b7ddf8128e782f957374c64f57aa2508ac3fe2/build/package.gni#304
    let mut cm_decl = read_cm("/pkg/meta/example.cm").expect("could not read cm file");

    // profile variant injects this protocol.
    if let Some(uses) = &mut cm_decl.uses {
        uses.retain(|u| match u {
            UseDecl::Protocol(decl) => {
                if decl.source_name == Some("fuchsia.debugdata.DebugData".to_owned()) {
                    assert_eq!(
                        decl,
                        &UseProtocolDecl {
                            source: Some(Ref::Debug(DebugRef {})),
                            source_name: Some("fuchsia.debugdata.DebugData".to_string()),
                            target_path: Some("/svc/fuchsia.debugdata.DebugData".to_string()),
                            ..UseProtocolDecl::EMPTY
                        }
                    );
                    return false;
                }
                return true;
            }
            _ => true,
        })
    }

    let expected_decl = {
        let program = ProgramDecl {
            runner: Some("elf".to_string()),
            info: Some(fdata::Dictionary {
                entries: Some(vec![
                    fdata::DictionaryEntry {
                        key: "binary".to_string(),
                        value: Some(Box::new(fdata::DictionaryValue::Str(
                            "bin/example".to_string(),
                        ))),
                    },
                    fdata::DictionaryEntry {
                        key: "lifecycle.stop_event".to_string(),
                        value: Some(Box::new(fdata::DictionaryValue::Str("notify".to_string()))),
                    },
                ]),
                ..fdata::Dictionary::EMPTY
            }),
            ..ProgramDecl::EMPTY
        };
        let uses = vec![
            UseDecl::Service(UseServiceDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("fuchsia.fonts.Provider".to_string()),
                target_path: Some("/svc/fuchsia.fonts.Provider".to_string()),
                ..UseServiceDecl::EMPTY
            }),
            UseDecl::Protocol(UseProtocolDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("fuchsia.fonts.LegacyProvider".to_string()),
                target_path: Some("/svc/fuchsia.fonts.OldProvider".to_string()),
                ..UseProtocolDecl::EMPTY
            }),
            UseDecl::Protocol(UseProtocolDecl {
                source: Some(Ref::Debug(DebugRef {})),
                source_name: Some("fuchsia.log.LegacyLog".to_string()),
                target_path: Some("/svc/fuchsia.log.LegacyLog".to_string()),
                ..UseProtocolDecl::EMPTY
            }),
            UseDecl::Event(UseEventDecl {
                source: Some(Ref::Framework(FrameworkRef {})),
                source_name: Some("started".to_string()),
                target_name: Some("began".to_string()),
                filter: None,
                mode: Some(EventMode::Async),
                ..UseEventDecl::EMPTY
            }),
            UseDecl::Event(UseEventDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("destroyed".to_string()),
                target_name: Some("destroyed".to_string()),
                filter: None,
                mode: Some(EventMode::Async),
                ..UseEventDecl::EMPTY
            }),
            UseDecl::Event(UseEventDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("stopped".to_string()),
                target_name: Some("stopped".to_string()),
                filter: None,
                mode: Some(EventMode::Async),
                ..UseEventDecl::EMPTY
            }),
            UseDecl::Event(UseEventDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("capability_ready".to_string()),
                target_name: Some("diagnostics_ready".to_string()),
                filter: Some(fdata::Dictionary {
                    entries: Some(vec![fdata::DictionaryEntry {
                        key: "path".to_string(),
                        value: Some(Box::new(fdata::DictionaryValue::Str(
                            "diagnostics".to_string(),
                        ))),
                    }]),
                    ..fdata::Dictionary::EMPTY
                }),
                mode: Some(EventMode::Async),
                ..UseEventDecl::EMPTY
            }),
            UseDecl::EventStream(UseEventStreamDecl {
                name: Some("my_stream".to_string()),
                subscriptions: Some(vec![
                    EventSubscription {
                        event_name: Some("began".to_string()),
                        mode: Some(EventMode::Async),
                        ..EventSubscription::EMPTY
                    },
                    EventSubscription {
                        event_name: Some("destroyed".to_string()),
                        mode: Some(EventMode::Async),
                        ..EventSubscription::EMPTY
                    },
                    EventSubscription {
                        event_name: Some("diagnostics_ready".to_string()),
                        mode: Some(EventMode::Sync),
                        ..EventSubscription::EMPTY
                    },
                ]),
                ..UseEventStreamDecl::EMPTY
            }),
            UseDecl::Protocol(UseProtocolDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("fuchsia.logger.LogSink".to_string()),
                target_path: Some("/svc/fuchsia.logger.LogSink".to_string()),
                ..UseProtocolDecl::EMPTY
            }),
        ];
        let exposes = vec![
            ExposeDecl::Service(ExposeServiceDecl {
                source: Some(Ref::Child(ChildRef { name: "logger".to_string(), collection: None })),
                source_name: Some("fuchsia.logger.Log".to_string()),
                target_name: Some("fuchsia.logger.Log".to_string()),
                target: Some(Ref::Parent(ParentRef {})),
                ..ExposeServiceDecl::EMPTY
            }),
            ExposeDecl::Protocol(ExposeProtocolDecl {
                source: Some(Ref::Child(ChildRef { name: "logger".to_string(), collection: None })),
                source_name: Some("fuchsia.logger.LegacyLog".to_string()),
                target_name: Some("fuchsia.logger.OldLog".to_string()),
                target: Some(Ref::Parent(ParentRef {})),
                ..ExposeProtocolDecl::EMPTY
            }),
            ExposeDecl::Directory(ExposeDirectoryDecl {
                source: Some(Ref::Self_(SelfRef {})),
                source_name: Some("blobfs".to_string()),
                target_name: Some("blobfs".to_string()),
                target: Some(Ref::Parent(ParentRef {})),
                rights: None,
                subdir: Some("blob".to_string()),
                ..ExposeDirectoryDecl::EMPTY
            }),
        ];
        let offers = vec![
            OfferDecl::Service(OfferServiceDecl {
                source: Some(Ref::Child(ChildRef { name: "logger".to_string(), collection: None })),
                source_name: Some("fuchsia.logger.Log".to_string()),
                target: Some(Ref::Collection(CollectionRef { name: "modular".to_string() })),
                target_name: Some("fuchsia.logger.Log".to_string()),
                ..OfferServiceDecl::EMPTY
            }),
            OfferDecl::Protocol(OfferProtocolDecl {
                source: Some(Ref::Child(ChildRef { name: "logger".to_string(), collection: None })),
                source_name: Some("fuchsia.logger.LegacyLog".to_string()),
                target: Some(Ref::Collection(CollectionRef { name: "modular".to_string() })),
                target_name: Some("fuchsia.logger.OldLog".to_string()),
                dependency_type: Some(DependencyType::Strong),
                ..OfferProtocolDecl::EMPTY
            }),
            OfferDecl::Event(OfferEventDecl {
                source: Some(Ref::Parent(ParentRef {})),
                source_name: Some("stopped".to_string()),
                target: Some(Ref::Child(ChildRef { name: "logger".to_string(), collection: None })),
                target_name: Some("stopped-logger".to_string()),
                filter: None,
                mode: Some(EventMode::Async),
                ..OfferEventDecl::EMPTY
            }),
        ];
        let capabilities = vec![
            CapabilityDecl::Service(ServiceDecl {
                name: Some("fuchsia.logger.Log".to_string()),
                source_path: Some("/svc/fuchsia.logger.Log".to_string()),
                ..ServiceDecl::EMPTY
            }),
            CapabilityDecl::Protocol(ProtocolDecl {
                name: Some("fuchsia.logger.Log2".to_string()),
                source_path: Some("/svc/fuchsia.logger.Log2".to_string()),
                ..ProtocolDecl::EMPTY
            }),
            CapabilityDecl::Directory(DirectoryDecl {
                name: Some("blobfs".to_string()),
                source_path: Some("/volumes/blobfs".to_string()),
                rights: Some(
                    fio2::Operations::Connect
                        | fio2::Operations::ReadBytes
                        | fio2::Operations::WriteBytes
                        | fio2::Operations::GetAttributes
                        | fio2::Operations::UpdateAttributes
                        | fio2::Operations::Enumerate
                        | fio2::Operations::Traverse
                        | fio2::Operations::ModifyDirectory,
                ),
                ..DirectoryDecl::EMPTY
            }),
            CapabilityDecl::Storage(StorageDecl {
                name: Some("minfs".to_string()),
                source: Some(Ref::Parent(ParentRef {})),
                backing_dir: Some("data".to_string()),
                subdir: None,
                storage_id: Some(StorageId::StaticInstanceIdOrMoniker),
                ..StorageDecl::EMPTY
            }),
            CapabilityDecl::Runner(RunnerDecl {
                name: Some("dart_runner".to_string()),
                source_path: Some("/svc/fuchsia.sys2.Runner".to_string()),
                ..RunnerDecl::EMPTY
            }),
            CapabilityDecl::Resolver(ResolverDecl {
                name: Some("pkg_resolver".to_string()),
                source_path: Some("/svc/fuchsia.pkg.Resolver".to_string()),
                ..ResolverDecl::EMPTY
            }),
        ];
        let children = vec![ChildDecl {
            name: Some("logger".to_string()),
            url: Some("fuchsia-pkg://fuchsia.com/logger/stable#meta/logger.cm".to_string()),
            startup: Some(StartupMode::Lazy),
            environment: Some("env_one".to_string()),
            ..ChildDecl::EMPTY
        }];
        let collections = vec![CollectionDecl {
            name: Some("modular".to_string()),
            durability: Some(Durability::Persistent),
            environment: None,
            ..CollectionDecl::EMPTY
        }];
        let facets = Object {
            entries: vec![
                Entry {
                    key: "author".to_string(),
                    value: Some(Box::new(Value::Str("Fuchsia".to_string()))),
                },
                Entry { key: "year".to_string(), value: Some(Box::new(Value::Inum(2018))) },
            ],
        };
        let envs = vec![
            EnvironmentDecl {
                name: Some("env_one".to_string()),
                extends: Some(EnvironmentExtends::None),
                stop_timeout_ms: Some(1337),
                runners: None,
                resolvers: None,
                debug_capabilities: None,
                ..EnvironmentDecl::EMPTY
            },
            EnvironmentDecl {
                name: Some("env_two".to_string()),
                extends: Some(EnvironmentExtends::Realm),
                stop_timeout_ms: None,
                runners: None,
                resolvers: None,
                debug_capabilities: Some(vec![
                    DebugRegistration::Protocol(DebugProtocolRegistration {
                        source_name: Some("fuchsia.logger.LegacyLog".to_string()),
                        source: Some(Ref::Child(ChildRef {
                            name: "logger".to_string(),
                            collection: None,
                        })),
                        target_name: Some("fuchsia.logger.LegacyLog".to_string()),
                        ..DebugProtocolRegistration::EMPTY
                    }),
                    DebugRegistration::Protocol(DebugProtocolRegistration {
                        source_name: Some("fuchsia.logger.OtherLog".to_string()),
                        source: Some(Ref::Parent(ParentRef {})),
                        target_name: Some("fuchsia.logger.OtherLog".to_string()),
                        ..DebugProtocolRegistration::EMPTY
                    }),
                    DebugRegistration::Protocol(DebugProtocolRegistration {
                        source_name: Some("fuchsia.logger.Log2".to_string()),
                        source: Some(Ref::Self_(SelfRef {})),
                        target_name: Some("fuchsia.logger.Log2".to_string()),
                        ..DebugProtocolRegistration::EMPTY
                    }),
                ]),
                ..EnvironmentDecl::EMPTY
            },
        ];
        ComponentDecl {
            program: Some(program),
            uses: Some(uses),
            exposes: Some(exposes),
            offers: Some(offers),
            capabilities: Some(capabilities),
            children: Some(children),
            collections: Some(collections),
            facets: Some(facets),
            environments: Some(envs),
            ..ComponentDecl::EMPTY
        }
    };
    assert_eq!(cm_decl, expected_decl);
}

fn read_cm(file: &str) -> Result<ComponentDecl, Error> {
    let mut buffer = Vec::new();
    let path = PathBuf::from(file);
    File::open(&path)?.read_to_end(&mut buffer)?;
    Ok(decode_persistent(&buffer)?)
}
