// Copyright 2019 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::inspect::zero_pad;
use super::typeface::{
    Collection as TypefaceCollection, Typeface, TypefaceCollectionBuilder, TypefaceId,
    TypefaceInfoAndCharSet, TypefaceInspectData,
};
use super::AssetId;
use fidl_fuchsia_fonts::GenericFontFamily;
use fuchsia_inspect as finspect;
use heck::KebabCase;
use itertools::Itertools;
use manifest::serde_ext::StyleOptions;
use manifest::v2;
use std::collections::BTreeMap;
use std::sync::Arc;
use unicase::UniCase;

#[derive(Debug, Eq, Hash, PartialEq)]
pub enum FamilyOrAlias {
    Family(FontFamily),
    /// The definition of a `Family`'s alias. This is a representation of the alias's _target_
    /// (value). The alias's name (key) is stored outside of this enum.
    ///
    /// * `UniCase<String>` - The _canonical_ family name.
    /// * `Option<Arc<TypefaceQueryOverrides>>` - Optional query overrides applied when a client
    ///    requests the associated alias.
    Alias(UniCase<String>, Option<Arc<TypefaceQueryOverrides>>),
}

/// Builder for [FamilyOrAlias].
#[derive(Debug)]
pub enum FamilyOrAliasBuilder {
    Family(FontFamilyBuilder),
    Alias(UniCase<String>, Option<Arc<TypefaceQueryOverrides>>),
}

impl FamilyOrAliasBuilder {
    /// Finalizes and builds a `FamilyOrAlias`.
    pub fn build(self) -> FamilyOrAlias {
        match self {
            FamilyOrAliasBuilder::Family(family_builder) => {
                FamilyOrAlias::Family(family_builder.build())
            }
            FamilyOrAliasBuilder::Alias(name, overrides) => FamilyOrAlias::Alias(name, overrides),
        }
    }

    /// Generates a full set of aliases from a given manifest v2 `Family`, including alias variants
    /// without spaces.
    pub fn aliases_from_family(
        manifest_family: &v2::Family,
    ) -> BTreeMap<UniCase<String>, FamilyOrAliasBuilder> {
        let mut output: BTreeMap<UniCase<String>, FamilyOrAliasBuilder> = BTreeMap::new();
        let family_name = UniCase::new(manifest_family.name.clone());
        let family_name_without_spaces = UniCase::new(manifest_family.name.replace(" ", ""));
        if family_name_without_spaces != family_name {
            output.insert(
                family_name_without_spaces,
                FamilyOrAliasBuilder::Alias(family_name.clone(), None),
            );
        }

        for alias_set in &manifest_family.aliases {
            let overrides = if alias_set.has_overrides() {
                Some(Arc::new(TypefaceQueryOverrides {
                    style: alias_set.style_overrides().clone(),
                    languages: alias_set.language_overrides().cloned().collect_vec(),
                }))
            } else {
                None
            };

            for alias_name in alias_set.names() {
                let alias_name = UniCase::new(alias_name.clone());
                output.insert(
                    alias_name.clone(),
                    FamilyOrAliasBuilder::Alias(family_name.clone(), overrides.clone()),
                );

                let alias_name_without_spaces = UniCase::new((*alias_name).replace(" ", ""));
                if alias_name != alias_name_without_spaces {
                    output.insert(
                        alias_name_without_spaces,
                        FamilyOrAliasBuilder::Alias(family_name.clone(), overrides.clone()),
                    );
                }
            }
        }

        output
    }
}

/// Optional set of typeface query overrides embedded in a `FontFamilyAlias`.
///
/// For example, the if a client asks for alias "Roboto Condensed", the server knows that means
/// means the canonical family "Roboto" with style `width: condensed`. If the client asks for "Noto
/// Sans CJK JP", that's interpreted as the canonical family "Noto Sans CJK" with
/// `languages: [ "ja" ]`.
///
#[derive(Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct TypefaceQueryOverrides {
    pub style: StyleOptions,
    pub languages: Vec<String>,
}

impl TypefaceQueryOverrides {
    pub fn has_style_overrides(&self) -> bool {
        self.style != StyleOptions::default()
    }

    pub fn has_language_overrides(&self) -> bool {
        !self.languages.is_empty()
    }
}

/// In-memory representation of metadata for a font family and its typefaces.
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct FontFamily {
    /// The family's canonical name
    pub name: String,
    /// Collection of typefaces in the family
    pub faces: TypefaceCollection,
    /// Generic font family that this family belongs to, if applicable
    pub generic_family: Option<GenericFontFamily>,
}

impl FontFamily {
    /// Get owned copies of the family's typefaces as `TypefaceInfo`
    pub fn extract_faces<'a>(&'a self) -> impl Iterator<Item = TypefaceInfoAndCharSet> + 'a {
        // Convert Vec<Arc<Typeface>> to Vec<TypefaceInfo>
        self.faces
            .faces
            .iter()
            // Copy most fields from `Typeface` and use the canonical family name
            .map(move |face| TypefaceInfoAndCharSet::from_typeface(face, self.name.clone()))
    }
}

/// Builder for [FontFamily].
#[derive(Debug)]
pub struct FontFamilyBuilder {
    /// The family's canonical name
    name: String,
    /// Generic font family that this family belongs to, if applicable
    generic_family: Option<GenericFontFamily>,
    /// Collection of typefaces in the family
    faces: TypefaceCollectionBuilder,
}

impl FontFamilyBuilder {
    /// Creates a new builder without any typefaces defined.
    pub fn new(
        name: impl Into<String>,
        generic_family: Option<GenericFontFamily>,
    ) -> FontFamilyBuilder {
        FontFamilyBuilder {
            name: name.into(),
            generic_family,
            faces: TypefaceCollectionBuilder::new(),
        }
    }

    /// Returns true if the family's typeface collection already has a typeface with the given ID.
    pub fn has_typeface_id(&self, typeface_id: &TypefaceId) -> bool {
        self.faces.has_typeface_id(typeface_id)
    }

    /// If there's no existing typeface with the same typeface ID already in the builder, adds the
    /// given typeface and and returns `true`. Otherwise, returns `false`.
    pub fn add_typeface_once(&mut self, typeface: Arc<Typeface>) -> bool {
        self.faces.add_typeface_once(typeface)
    }

    /// Finalizes and builds a `FontFamily`.
    pub fn build(self) -> FontFamily {
        FontFamily {
            name: self.name,
            faces: self.faces.build(),
            generic_family: self.generic_family,
        }
    }
}

/// Inspect data for a `FontFamily`.
#[derive(Debug)]
pub struct FamilyInspectData {
    // TODO(https://fxbug.dev/42165549)
    #[allow(unused)]
    node: finspect::Node,

    aliases_node: finspect::Node,
    aliases: Vec<AliasInspectData>,

    // TODO(https://fxbug.dev/42165549)
    #[allow(unused)]
    typefaces_node: finspect::Node,
    // TODO(https://fxbug.dev/42165549)
    #[allow(unused)]
    typefaces: Vec<TypefaceInspectData>,
}

impl FamilyInspectData {
    /// Creates a new `FamilyInspectData`.
    pub fn new(
        parent: &finspect::Node,
        family: &FontFamily,
        asset_location_lookup: &impl Fn(AssetId) -> Option<String>,
    ) -> Self {
        let node = parent.create_child(&family.name);

        let aliases_node = node.create_child("aliases");
        let aliases: Vec<AliasInspectData> = Vec::new();

        let typefaces_node = node.create_child("typefaces");
        let typefaces_count = family.faces.faces.len();
        let typefaces: Vec<TypefaceInspectData> = family
            .faces
            .faces
            .iter()
            .enumerate()
            .map(|(idx, typeface)| {
                TypefaceInspectData::new(
                    &typefaces_node,
                    &zero_pad(idx, typefaces_count),
                    typeface,
                    asset_location_lookup,
                )
            })
            .collect();

        FamilyInspectData { node, aliases_node, aliases, typefaces_node, typefaces }
    }

    /// Adds a new font family alias, optionally with query overrides, to the existing Inspect data.
    pub fn add_alias(&mut self, alias: &str, overrides: &Option<Arc<TypefaceQueryOverrides>>) {
        let alias_data = AliasInspectData::new(&self.aliases_node, alias, overrides);
        self.aliases.push(alias_data);
    }
}

/// Inspect data for a single font family alias.
#[derive(Debug)]
pub struct AliasInspectData {
    // TODO(https://fxbug.dev/42165549)
    #[allow(unused)]
    node: finspect::Node,
    // TODO(https://fxbug.dev/42165549)
    #[allow(unused)]
    style_overrides: Option<finspect::Node>,
    // TODO(https://fxbug.dev/42165549)
    #[allow(unused)]
    language_overrides: Option<finspect::StringProperty>,
}

impl AliasInspectData {
    /// Creates a new `AliasInspectData`.
    fn new(
        parent_inspect_node: &finspect::Node,
        alias: &str,
        overrides: &Option<Arc<TypefaceQueryOverrides>>,
    ) -> Self {
        let node = parent_inspect_node.create_child(alias);

        let style_overrides = overrides.as_ref().and_then(|overrides| {
            if overrides.has_style_overrides() {
                let style = node.create_child("style_overrides");
                if let Some(slant) = overrides.style.slant {
                    style.record_string("slant", format!("{:?}", slant).to_kebab_case());
                }
                if let Some(weight) = overrides.style.weight {
                    style.record_uint("weight", weight.into());
                }
                if let Some(width) = overrides.style.width {
                    style.record_string("width", format!("{:?}", width).to_kebab_case());
                }
                Some(style)
            } else {
                None
            }
        });

        let language_overrides = overrides.as_ref().and_then(|overrides| {
            if overrides.has_language_overrides() {
                Some(
                    node.create_string("language_overrides", overrides.languages.iter().join(", ")),
                )
            } else {
                None
            }
        });

        AliasInspectData { node, style_overrides, language_overrides }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use anyhow::Error;
    use char_collection::char_collect;
    use diagnostics_assertions::assert_data_tree;
    use fidl_fuchsia_fonts::{Slant, Width};
    use maplit::{btreemap, btreeset};
    use pretty_assertions::assert_eq;

    #[fuchsia::test]
    fn test_aliases_from_family() -> Result<(), Error> {
        let family = v2::Family {
            name: "Family A".to_string(),
            aliases: vec![
                v2::FontFamilyAliasSet::without_overrides(vec!["A Family", "Family Ay"])?,
                v2::FontFamilyAliasSet::new(
                    vec!["Family A Condensed", "Family A Squished"],
                    StyleOptions { width: Some(Width::Condensed), ..Default::default() },
                    std::iter::empty::<String>(),
                )?,
            ],
            generic_family: None,
            assets: vec![],
        };

        let expected = btreemap! {
            UniCase::new("FamilyA".to_string()) =>
                FamilyOrAlias::Alias(UniCase::new("Family A".to_string()), None),
            UniCase::new("A Family".to_string()) =>
                FamilyOrAlias::Alias(UniCase::new("Family A".to_string()), None),
            UniCase::new("AFamily".to_string()) =>
                FamilyOrAlias::Alias(UniCase::new("Family A".to_string()), None),
            UniCase::new("Family A Condensed".to_string()) =>
                FamilyOrAlias::Alias(
                    UniCase::new("Family A".to_string()),
                    Some(Arc::new(
                            TypefaceQueryOverrides {
                                style: StyleOptions {
                                    width: Some(Width::Condensed),
                                    ..Default::default()
                                },
                                languages: vec![]
                            }
                        ))
                ),
            UniCase::new("FamilyACondensed".to_string()) =>
                FamilyOrAlias::Alias(
                    UniCase::new("Family A".to_string()),
                    Some(Arc::new(
                            TypefaceQueryOverrides {
                                style: StyleOptions {
                                    width: Some(Width::Condensed),
                                    ..Default::default()
                                },
                                languages: vec![]
                            }
                        ))
                ),
            UniCase::new("Family A Squished".to_string()) =>
                FamilyOrAlias::Alias(
                    UniCase::new("Family A".to_string()),
                    Some(Arc::new(
                            TypefaceQueryOverrides {
                                style: StyleOptions {
                                    width: Some(Width::Condensed),
                                    ..Default::default()
                                },
                                languages: vec![]
                            }
                        ))
                ),
            UniCase::new("FamilyASquished".to_string()) =>
                FamilyOrAlias::Alias(
                    UniCase::new("Family A".to_string()),
                    Some(Arc::new(
                            TypefaceQueryOverrides {
                                style: StyleOptions {
                                    width: Some(Width::Condensed),
                                    ..Default::default()
                                },
                                languages: vec![]
                            }
                        ))
                ),
            UniCase::new("Family Ay".to_string()) =>
                FamilyOrAlias::Alias(UniCase::new("Family A".to_string()), None),
            UniCase::new("FamilyAy".to_string()) =>
                FamilyOrAlias::Alias(UniCase::new("Family A".to_string()), None),
        };

        let actual: BTreeMap<UniCase<String>, FamilyOrAlias> =
            FamilyOrAliasBuilder::aliases_from_family(&family)
                .into_iter()
                .map(|(key, val)| (key, val.build()))
                .collect();

        assert_eq!(expected, actual);

        Ok(())
    }

    #[fuchsia::test]
    fn test_alias_inspect_data() {
        let alias = "Alif";
        let overrides = Some(Arc::new(TypefaceQueryOverrides {
            style: StyleOptions {
                slant: None,
                weight: Some(600),
                width: Some(Width::ExtraExpanded),
            },
            languages: vec!["ar-EG".to_string(), "ar-MA".to_string()],
        }));

        let inspector = finspect::Inspector::default();
        let _inspect_data = AliasInspectData::new(inspector.root(), alias, &overrides);
        assert_data_tree!(inspector, root: {
            Alif: {
                style_overrides: {
                    weight: 600u64,
                    width: "extra-expanded"
                },
                language_overrides: "ar-EG, ar-MA"
            }
        });
    }

    #[fuchsia::test]
    fn test_family_inspect_data() {
        let mut family = FontFamilyBuilder::new("Alpha", Some(GenericFontFamily::Cursive));
        family.add_typeface_once(Arc::new(Typeface {
            asset_id: AssetId(0),
            font_index: 0,
            slant: Slant::Upright,
            weight: 400,
            width: Width::Normal,
            languages: btreeset!("ar-EG".to_string(), "ar-MA".to_string()),
            char_set: char_collect!(0x0..=0xEE).into(),
            generic_family: Some(GenericFontFamily::Cursive),
        }));
        family.add_typeface_once(Arc::new(Typeface {
            asset_id: AssetId(1),
            font_index: 0,
            slant: Slant::Upright,
            weight: 400,
            width: Width::UltraCondensed,
            languages: btreeset!("und-Latn".to_string()),
            char_set: char_collect!(0x0..=0xEE).into(),
            generic_family: Some(GenericFontFamily::Cursive),
        }));
        let family = family.build();

        let asset_location_lookup = |asset_id| match asset_id {
            AssetId(0) => Some("/path/to/asset-0.ttf".to_string()),
            AssetId(1) => Some("/path/to/asset-1.ttf".to_string()),
            _ => unreachable!(),
        };

        let inspector = finspect::Inspector::default();
        let mut inspect_data =
            FamilyInspectData::new(inspector.root(), &family, &asset_location_lookup);
        inspect_data.add_alias(
            "Alif",
            &Some(Arc::new(TypefaceQueryOverrides {
                style: StyleOptions::default(),
                languages: vec!["ar-EG".to_string(), "ar-JO".to_string()],
            })),
        );
        inspect_data.add_alias("Ay", &None);

        // The contents of `AliasInspectData` and `TypefaceInspectData` are tested in their
        // respective unit tests. This test just asserts the overall structure.
        assert_data_tree!(inspector, root: {
            Alpha: {
                aliases: {
                    Ay: contains {},
                    Alif: contains {},
                },
                typefaces: {
                    "0": contains {
                        asset_location: "/path/to/asset-0.ttf",
                    },
                    "1": contains {
                        asset_location: "/path/to/asset-1.ttf",
                    },
                }
            }
        });
    }
}
