// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::{warnings::Warning, SYSTEM_TEST_SHARD};
use anyhow::{bail, Context, Error};
use once_cell::sync::Lazy;
use serde::Deserialize;
use std::collections::{BTreeMap, BTreeSet};

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CmxFacets {
    #[serde(rename = "fuchsia.test")]
    test: Option<TestFacets>,

    #[serde(rename = "fuchsia.module")]
    #[allow(unused)] // included for confidence in completeness of cmx parser but unsupported
    module: Option<CmxModule>,
}

impl CmxFacets {
    /// Convert the facets into the appropriate shards and `use`s in CML, returning the set of
    /// protocols received from children.
    pub fn convert(
        &self,
        include: &mut BTreeSet<String>,
        uses: &mut Vec<cml::Use>,
        children: &mut Vec<cml::Child>,
        warnings: &mut BTreeSet<Warning>,
    ) -> Result<BTreeSet<String>, Error> {
        let mut injected = BTreeSet::new();
        if let Some(test) = &self.test {
            injected = test.convert(include, uses, children, warnings)?;
        }

        if self.module.is_some() {
            bail!("fuchsia modules are not supported by this converter");
        }

        Ok(injected)
    }
}

#[derive(Debug, Deserialize)]
#[allow(unused)] // included for completeness of parser on in-tree cmx files but unsupported
#[serde(deny_unknown_fields)]
struct CmxModule {
    #[serde(rename = "@version")]
    version: u8,
    intent_filters: Vec<serde_json::Value>,
    suggestion_headline: String,
    composition_pattern: String,
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct TestFacets {
    #[serde(rename = "injected-services")]
    injected: Option<BTreeMap<String, InjectedService>>,
    #[serde(rename = "system-services")]
    system: Option<Vec<String>>,
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields, untagged)]
enum InjectedService {
    Url(String),
    UrlWithArgs(Vec<String>),
}

impl TestFacets {
    /// Convert test facets, returning the set of all protocols that come from injected children.
    pub fn convert(
        &self,
        include: &mut BTreeSet<String>,
        uses: &mut Vec<cml::Use>,
        children: &mut Vec<cml::Child>,
        warnings: &mut BTreeSet<Warning>,
    ) -> Result<BTreeSet<String>, Error> {
        let mut injected_protocols = BTreeSet::new();
        if let Some(injected) = &self.injected {
            // for each injected service, add a child and use the protocol from it
            // do this in a separate loop from modifying cml so that we can group things
            let mut children_by_name: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
            for (protocol, v1_provider) in injected {
                if let InjectedService::UrlWithArgs(..) = v1_provider {
                    bail!("injected services that pass arguments are not supported");
                }
                let (url, InjectedServiceProvider { name, gn_target }) =
                    if let Some(p) = InjectedServicesMap::provider(protocol)? {
                        p
                    } else {
                        // this protocol doesn't need a static child in v2, get it from parent
                        // v1 protocols needed to be be in sandbox already, so just skip this one
                        // before we remove it from existing uses from parent
                        continue;
                    };

                children_by_name.entry((name, url, gn_target)).or_default().insert(protocol);
                injected_protocols.insert(protocol.to_owned());
            }

            for ((name, url, gn_target), protocols) in children_by_name {
                let child_name =
                    cml::Name::new(&name).with_context(|| format!("declaring child {name}"))?;
                let url =
                    cml::Url::new(&url).with_context(|| format!("parsing {url} as a CML URL"))?;

                warnings.insert(Warning::ChildNeedsGnTargetAndRouting {
                    child: name.clone(),
                    gn_target,
                });
                children.push(cml::Child {
                    name: child_name.clone(),
                    url,
                    startup: cml::StartupMode::Lazy,
                    on_terminate: None,
                    environment: None,
                });

                let protocols = protocols
                    .into_iter()
                    .map(|p| {
                        cml::Name::new(p)
                            .with_context(|| format!("defining name for use decl for {p}"))
                    })
                    .collect::<Result<Vec<_>, _>>()?;
                uses.push(cml::Use {
                    protocol: Some(cml::OneOrMany::Many(protocols)),
                    from: Some(cml::UseFromRef::Named(child_name)),
                    ..Default::default()
                });
            }
        }

        if self.system.is_some() {
            // system tests get a different test realm, spell this as a shard
            include.insert(SYSTEM_TEST_SHARD.to_string());

            // in v1, system services need to be spelled twice, so we already have a `use` for them
        }

        Ok(injected_protocols)
    }
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct InjectedServicesMap {
    protocols: BTreeMap<String, String>,
    components: BTreeMap<String, InjectedServiceProvider>,
}

static INJECTED_SERVICES_MAP: Lazy<InjectedServicesMap> = Lazy::new(|| {
    static MAP_RAW: &str = include_str!("../injected_services_map.json5");
    let parsed: InjectedServicesMap =
        serde_json5::from_str(MAP_RAW).expect("injected services map must be valid json");
    parsed
});

impl InjectedServicesMap {
    /// Returns the URL and provider info for a given protocol's injected service provider if
    /// available. Returns `None` if the protocol should be retrieved from `parent` in v2 tests.
    pub fn provider(protocol: &str) -> Result<Option<(String, InjectedServiceProvider)>, Error> {
        if let Some(url) = INJECTED_SERVICES_MAP.protocols.get(protocol) {
            if url == "parent" {
                return Ok(None);
            }
            if let Some(provider) = INJECTED_SERVICES_MAP.components.get(url) {
                Ok(Some((url.to_owned(), provider.to_owned())))
            } else {
                bail!("`{protocol}`'s provider {url} does not have a registered implementation");
            }
        } else {
            bail!("`{protocol}` does not have a registered provider for injection");
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct InjectedServiceProvider {
    /// the name of the static child for the provider
    pub name: String,

    /// the GN target that must be added to a package to have access to the provider
    pub gn_target: String,
}
