// 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 {
    argh::FromArgs,
    cm_types::{symmetrical_enums, Url},
    cml::error::{Error, Location},
    fidl::encoding::encode_persistent,
    fidl_fuchsia_component_internal as component_internal, fidl_fuchsia_sys2 as fsys,
    serde::Deserialize,
    serde_json5,
    std::{
        collections::HashSet,
        convert::{TryFrom, TryInto},
        fs::{self, File},
        io::Write,
        path::PathBuf,
    },
};

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
struct Config {
    debug: Option<bool>,
    list_children_batch_size: Option<u32>,
    security_policy: Option<SecurityPolicy>,
    namespace_capabilities: Option<Vec<cml::Capability>>,
    use_builtin_process_launcher: Option<bool>,
    maintain_utc_clock: Option<bool>,
    num_threads: Option<u32>,
    builtin_pkg_resolver: Option<BuiltinPkgResolver>,
    out_dir_contents: Option<OutDirContents>,
    root_component_url: Option<Url>,
    component_id_index_path: Option<String>,
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
enum BuiltinPkgResolver {
    None,
    AppmgrBridge,
}

symmetrical_enums!(BuiltinPkgResolver, component_internal::BuiltinPkgResolver, None, AppmgrBridge);

impl std::default::Default for BuiltinPkgResolver {
    fn default() -> Self {
        BuiltinPkgResolver::None
    }
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct SecurityPolicy {
    job_policy: Option<JobPolicyAllowlists>,
    capability_policy: Option<Vec<CapabilityAllowlistEntry>>,
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct JobPolicyAllowlists {
    ambient_mark_vmo_exec: Option<Vec<String>>,
    main_process_critical: Option<Vec<String>>,
}

#[derive(Deserialize, Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(u32)]
#[serde(rename_all = "snake_case")]
pub enum OutDirContents {
    None,
    Hub,
    Svc,
}

symmetrical_enums!(OutDirContents, component_internal::OutDirContents, None, Hub, Svc);

impl std::default::Default for OutDirContents {
    fn default() -> Self {
        OutDirContents::None
    }
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum CapabilityTypeName {
    Directory,
    Event,
    Protocol,
    Service,
    Storage,
    Runner,
    Resolver,
}

impl Into<component_internal::AllowlistedCapability> for CapabilityTypeName {
    fn into(self) -> component_internal::AllowlistedCapability {
        match &self {
            CapabilityTypeName::Directory => component_internal::AllowlistedCapability::Directory(
                component_internal::AllowlistedDirectory::EMPTY,
            ),
            CapabilityTypeName::Event => component_internal::AllowlistedCapability::Event(
                component_internal::AllowlistedEvent::EMPTY,
            ),
            CapabilityTypeName::Protocol => component_internal::AllowlistedCapability::Protocol(
                component_internal::AllowlistedProtocol::EMPTY,
            ),
            CapabilityTypeName::Service => component_internal::AllowlistedCapability::Service(
                component_internal::AllowlistedService::EMPTY,
            ),
            CapabilityTypeName::Storage => component_internal::AllowlistedCapability::Storage(
                component_internal::AllowlistedStorage::EMPTY,
            ),
            CapabilityTypeName::Runner => component_internal::AllowlistedCapability::Runner(
                component_internal::AllowlistedRunner::EMPTY,
            ),
            CapabilityTypeName::Resolver => component_internal::AllowlistedCapability::Resolver(
                component_internal::AllowlistedResolver::EMPTY,
            ),
        }
    }
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum CapabilityFrom {
    Capability,
    Component,
    Framework,
}

impl Into<fsys::Ref> for CapabilityFrom {
    fn into(self) -> fsys::Ref {
        match &self {
            CapabilityFrom::Capability => {
                fsys::Ref::Capability(fsys::CapabilityRef { name: "".into() })
            }
            CapabilityFrom::Component => fsys::Ref::Self_(fsys::SelfRef {}),
            CapabilityFrom::Framework => fsys::Ref::Framework(fsys::FrameworkRef {}),
        }
    }
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct CapabilityAllowlistEntry {
    source_moniker: Option<String>,
    source_name: Option<String>,
    source: Option<CapabilityFrom>,
    capability: Option<CapabilityTypeName>,
    target_monikers: Option<Vec<String>>,
}

impl TryFrom<Config> for component_internal::Config {
    type Error = Error;

    fn try_from(config: Config) -> Result<Self, Error> {
        // Validate "namespace_capabilities".
        if let Some(capabilities) = config.namespace_capabilities.as_ref() {
            let mut used_ids = HashSet::new();
            for capability in capabilities {
                Config::validate_capability(capability, &mut used_ids)?;
            }
        }

        Ok(Self {
            debug: config.debug,
            use_builtin_process_launcher: config.use_builtin_process_launcher,
            maintain_utc_clock: config.maintain_utc_clock,
            list_children_batch_size: config.list_children_batch_size,
            security_policy: Some(translate_security_policy(config.security_policy)),
            builtin_pkg_resolver: match config.builtin_pkg_resolver {
                Some(builtin_pkg_resolver) => Some(builtin_pkg_resolver.into()),
                None => None,
            },
            namespace_capabilities: config
                .namespace_capabilities
                .as_ref()
                .map(|c| cml::translate::translate_capabilities(c))
                .transpose()?,
            num_threads: config.num_threads,
            out_dir_contents: match config.out_dir_contents {
                Some(out_dir_contents) => Some(out_dir_contents.into()),
                None => None,
            },
            root_component_url: match config.root_component_url {
                Some(root_component_url) => Some(root_component_url.as_str().to_string()),
                None => None,
            },
            component_id_index_path: config.component_id_index_path,
            ..Self::EMPTY
        })
    }
}

// TODO: Instead of returning a "default" security_policy when it's not specified in JSON,
// could we return None instead?
fn translate_security_policy(
    security_policy: Option<SecurityPolicy>,
) -> component_internal::SecurityPolicy {
    let SecurityPolicy { job_policy, capability_policy } = security_policy.unwrap_or_default();
    component_internal::SecurityPolicy {
        job_policy: job_policy.map(translate_job_policy),
        capability_policy: capability_policy.map(translate_capability_policy),
        ..component_internal::SecurityPolicy::EMPTY
    }
}

fn translate_job_policy(
    job_policy: JobPolicyAllowlists,
) -> component_internal::JobPolicyAllowlists {
    component_internal::JobPolicyAllowlists {
        ambient_mark_vmo_exec: job_policy.ambient_mark_vmo_exec,
        main_process_critical: job_policy.main_process_critical,
        ..component_internal::JobPolicyAllowlists::EMPTY
    }
}

fn translate_capability_policy(
    capability_policy: Vec<CapabilityAllowlistEntry>,
) -> component_internal::CapabilityPolicyAllowlists {
    let allowlist = capability_policy
        .iter()
        .map(|e| component_internal::CapabilityAllowlistEntry {
            source_moniker: e.source_moniker.clone(),
            source_name: e.source_name.clone(),
            source: e.source.clone().map_or_else(|| None, |t| Some(t.into())),
            capability: e.capability.clone().map_or_else(|| None, |t| Some(t.into())),
            target_monikers: e.target_monikers.clone(),
            ..component_internal::CapabilityAllowlistEntry::EMPTY
        })
        .collect::<Vec<_>>();
    component_internal::CapabilityPolicyAllowlists {
        allowlist: Some(allowlist),
        ..component_internal::CapabilityPolicyAllowlists::EMPTY
    }
}

macro_rules! extend_if_unset {
    ( $($target:expr, $value:expr, $field:ident)+ ) => {
        $(
            $target.$field = match (&$target.$field, &$value.$field) {
                (Some(_), Some(_)) => {
                    return Err(Error::parse(
                        format!("Conflicting field found: {:?}", stringify!($field)),
                        None,
                        None,
                    ))
                }
                (None, Some(_)) => $value.$field,
                (Some(_), None) => $target.$field,
                (&None, &None) => None,
            };
        )+
    };
}

impl Config {
    fn from_json_file(path: &PathBuf) -> Result<Self, Error> {
        let data = fs::read_to_string(path)?;
        serde_json5::from_str(&data).map_err(|e| {
            let serde_json5::Error::Message { location, msg } = e;
            let location = location.map(|l| Location { line: l.line, column: l.column });
            Error::parse(msg, location, Some(path))
        })
    }

    fn extend(mut self, another: Config) -> Result<Self, Error> {
        extend_if_unset!(self, another, debug);
        extend_if_unset!(self, another, use_builtin_process_launcher);
        extend_if_unset!(self, another, maintain_utc_clock);
        extend_if_unset!(self, another, list_children_batch_size);
        extend_if_unset!(self, another, security_policy);
        extend_if_unset!(self, another, namespace_capabilities);
        extend_if_unset!(self, another, num_threads);
        extend_if_unset!(self, another, builtin_pkg_resolver);
        extend_if_unset!(self, another, out_dir_contents);
        extend_if_unset!(self, another, root_component_url);
        extend_if_unset!(self, another, component_id_index_path);
        Ok(self)
    }

    fn validate_capability(
        capability: &cml::Capability,
        used_ids: &mut HashSet<String>,
    ) -> Result<(), Error> {
        if capability.directory.is_some() && capability.path.is_none() {
            return Err(Error::validate("\"path\" should be present with \"directory\""));
        }
        if capability.directory.is_some() && capability.rights.is_none() {
            return Err(Error::validate("\"rights\" should be present with \"directory\""));
        }
        if capability.storage.is_some() {
            return Err(Error::validate("\"storage\" is not supported for namespace capabilities"));
        }
        if capability.runner.is_some() {
            return Err(Error::validate("\"runner\" is not supported for namespace capabilities"));
        }
        if capability.resolver.is_some() {
            return Err(Error::validate(
                "\"resolver\" is not supported for namespace capabilities",
            ));
        }

        // Disallow multiple capability ids of the same name.
        let capability_ids =
            cml::CapabilityId::from_clause(capability, cml::RoutingClauseType::Capability)?;
        for capability_id in capability_ids {
            if !used_ids.insert(capability_id.to_string()) {
                return Err(Error::validate(format!(
                    "\"{}\" is a duplicate \"capability\" name",
                    capability_id,
                )));
            }
        }

        Ok(())
    }
}

#[derive(Debug, Default, FromArgs)]
/// Create a binary config and populate it with data from .json file.
struct Args {
    /// path to a JSON configuration file
    #[argh(option)]
    input: Vec<PathBuf>,

    /// path to the output binary config file
    #[argh(option)]
    output: PathBuf,
}

pub fn from_args() -> Result<(), Error> {
    compile(argh::from_env())
}

fn compile(args: Args) -> Result<(), Error> {
    let configs =
        args.input.iter().map(Config::from_json_file).collect::<Result<Vec<Config>, _>>()?;
    let config_json =
        configs.into_iter().try_fold(Config::default(), |acc, next| acc.extend(next))?;

    let mut config_fidl: component_internal::Config = config_json.try_into()?;
    let bytes = encode_persistent(&mut config_fidl).map_err(|e| Error::FidlEncoding(e))?;
    let mut file = File::create(args.output).map_err(|e| Error::Io(e))?;
    file.write_all(&bytes).map_err(|e| Error::Io(e))?;
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use {
        fidl::encoding::decode_persistent, fidl_fuchsia_io2 as fio2, fidl_fuchsia_sys2 as fsys,
        matches::assert_matches, std::io::Read, tempfile::TempDir,
    };

    fn compile_str(input: &str) -> Result<component_internal::Config, Error> {
        let tmp_dir = TempDir::new().unwrap();
        let input_path = tmp_dir.path().join("config.json");
        let output_path = tmp_dir.path().join("config.fidl");
        File::create(&input_path).unwrap().write_all(input.as_bytes()).unwrap();
        let args = Args { output: output_path.clone(), input: vec![input_path] };
        compile(args)?;
        let mut bytes = Vec::new();
        File::open(output_path)?.read_to_end(&mut bytes)?;
        let config: component_internal::Config = decode_persistent(&bytes)?;
        Ok(config)
    }

    #[test]
    fn test_compile() {
        let input = r#"{
            debug: true,
            list_children_batch_size: 123,
            maintain_utc_clock: false,
            use_builtin_process_launcher: true,
            builtin_pkg_resolver: "appmgr_bridge",
            security_policy: {
                job_policy: {
                    main_process_critical: [ "/", "/bar" ],
                    ambient_mark_vmo_exec: ["/foo"],
                },
                capability_policy: [
                    {
                        source_moniker: "<component_manager>",
                        source: "component",
                        source_name: "fuchsia.kernel.RootResource",
                        capability: "protocol",
                        target_monikers: ["/root", "/root/bootstrap", "/root/core"],
                    },
                    {
                        source_moniker: "/foo/bar",
                        source_name: "running",
                        source: "framework",
                        capability: "event",
                        target_monikers: ["/foo/bar", "/foo/bar/baz"],
                    },
                ]
            },
            namespace_capabilities: [
                {
                    protocol: "foo_svc",
                },
                {
                    directory: "bar_dir",
                    path: "/bar",
                    rights: [ "connect" ],
                },
            ],
            num_threads: 321,
            out_dir_contents: "svc",
            root_component_url: "fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx",
            component_id_index_path: "/this/is/an/absolute/path",
        }"#;
        let config = compile_str(input).expect("failed to compile");
        assert_eq!(
            config,
            component_internal::Config {
                debug: Some(true),
                maintain_utc_clock: Some(false),
                use_builtin_process_launcher: Some(true),
                list_children_batch_size: Some(123),
                builtin_pkg_resolver: Some(component_internal::BuiltinPkgResolver::AppmgrBridge),
                security_policy: Some(component_internal::SecurityPolicy {
                    job_policy: Some(component_internal::JobPolicyAllowlists {
                        main_process_critical: Some(vec!["/".to_string(), "/bar".to_string()]),
                        ambient_mark_vmo_exec: Some(vec!["/foo".to_string()]),
                        ..component_internal::JobPolicyAllowlists::EMPTY
                    }),
                    capability_policy: Some(component_internal::CapabilityPolicyAllowlists {
                        allowlist: Some(vec![
                            component_internal::CapabilityAllowlistEntry {
                                source_moniker: Some("<component_manager>".to_string()),
                                source_name: Some("fuchsia.kernel.RootResource".to_string()),
                                source: Some(fsys::Ref::Self_(fsys::SelfRef {})),
                                capability: Some(
                                    component_internal::AllowlistedCapability::Protocol(
                                        component_internal::AllowlistedProtocol::EMPTY
                                    )
                                ),
                                target_monikers: Some(vec![
                                    "/root".to_string(),
                                    "/root/bootstrap".to_string(),
                                    "/root/core".to_string()
                                ]),
                                ..component_internal::CapabilityAllowlistEntry::EMPTY
                            },
                            component_internal::CapabilityAllowlistEntry {
                                source_moniker: Some("/foo/bar".to_string()),
                                capability: Some(component_internal::AllowlistedCapability::Event(
                                    component_internal::AllowlistedEvent::EMPTY
                                )),
                                source_name: Some("running".to_string()),
                                source: Some(fsys::Ref::Framework(fsys::FrameworkRef {})),
                                target_monikers: Some(vec![
                                    "/foo/bar".to_string(),
                                    "/foo/bar/baz".to_string()
                                ]),
                                ..component_internal::CapabilityAllowlistEntry::EMPTY
                            },
                        ]),
                        ..component_internal::CapabilityPolicyAllowlists::EMPTY
                    }),
                    ..component_internal::SecurityPolicy::EMPTY
                }),
                namespace_capabilities: Some(vec![
                    fsys::CapabilityDecl::Protocol(fsys::ProtocolDecl {
                        name: Some("foo_svc".into()),
                        source_path: Some("/svc/foo_svc".into()),
                        ..fsys::ProtocolDecl::EMPTY
                    }),
                    fsys::CapabilityDecl::Directory(fsys::DirectoryDecl {
                        name: Some("bar_dir".into()),
                        source_path: Some("/bar".into()),
                        rights: Some(fio2::Operations::Connect),
                        ..fsys::DirectoryDecl::EMPTY
                    }),
                ]),
                num_threads: Some(321),
                out_dir_contents: Some(component_internal::OutDirContents::Svc),
                root_component_url: Some("fuchsia-pkg://fuchsia.com/foo#meta/foo.cmx".to_string()),
                component_id_index_path: Some("/this/is/an/absolute/path".to_string()),
                ..component_internal::Config::EMPTY
            }
        );
    }

    #[test]
    fn test_validate_namespace_capabilities() {
        {
            let input = r#"{
            namespace_capabilities: [
                {
                    protocol: "foo",
                },
                {
                    directory: "foo",
                    path: "/foo",
                    rights: [ "connect" ],
                },
            ],
        }"#;
            assert_matches!(
                compile_str(input),
                Err(Error::Validate { schema_name: None, err, .. } )
                    if &err == "\"foo\" is a duplicate \"capability\" name"
            );
        }
        {
            let input = r#"{
            namespace_capabilities: [
                {
                    directory: "foo",
                    path: "/foo",
                },
            ],
        }"#;
            assert_matches!(
                compile_str(input),
                Err(Error::Validate { schema_name: None, err, .. } )
                    if &err == "\"rights\" should be present with \"directory\""
            );
        }
        {
            let input = r#"{
            namespace_capabilities: [
                {
                    directory: "foo",
                    rights: [ "connect" ],
                },
            ],
        }"#;
            assert_matches!(
                compile_str(input),
                Err(Error::Validate { schema_name: None, err, .. } )
                    if &err == "\"path\" should be present with \"directory\""
            );
        }
    }

    #[test]
    fn test_compile_conflict() {
        let tmp_dir = TempDir::new().unwrap();
        let output_path = tmp_dir.path().join("config");

        let input_path = tmp_dir.path().join("foo.json");
        let input = "{\"debug\": true,}";
        File::create(&input_path).unwrap().write_all(input.as_bytes()).unwrap();

        let another_input_path = tmp_dir.path().join("bar.json");
        let another_input = "{\"debug\": false,}";
        File::create(&another_input_path).unwrap().write_all(another_input.as_bytes()).unwrap();

        let args =
            Args { output: output_path.clone(), input: vec![input_path, another_input_path] };
        assert_matches!(compile(args), Err(Error::Parse { .. }));
    }

    #[test]
    fn test_merge() -> Result<(), Error> {
        let tmp_dir = TempDir::new().unwrap();
        let output_path = tmp_dir.path().join("config");

        let input_path = tmp_dir.path().join("foo.json");
        let input = "{\"debug\": true,}";
        File::create(&input_path).unwrap().write_all(input.as_bytes()).unwrap();

        let another_input_path = tmp_dir.path().join("bar.json");
        let another_input = "{\"list_children_batch_size\": 42,}";
        File::create(&another_input_path).unwrap().write_all(another_input.as_bytes()).unwrap();

        let args =
            Args { output: output_path.clone(), input: vec![input_path, another_input_path] };
        compile(args)?;

        let mut bytes = Vec::new();
        File::open(output_path)?.read_to_end(&mut bytes)?;
        let config: component_internal::Config = decode_persistent(&bytes)?;
        assert_eq!(config.debug, Some(true));
        assert_eq!(config.list_children_batch_size, Some(42));
        Ok(())
    }

    #[test]
    fn test_invalid_component_url() {
        let input = r#"{
            root_component_url: "not quite a valid Url",
        }"#;
        assert_matches!(compile_str(input), Err(Error::Parse { .. }));
    }
}
