// Copyright 2018 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::{
        matcher::select_best_match,
        typeface::{Typeface, TypefaceAndLangScore, TypefaceId},
    },
    anyhow::{format_err, Error},
    char_set::CharSet,
    fidl_fuchsia_fonts::{Style2, TypefaceQuery, TypefaceRequest},
    fidl_fuchsia_fonts_ext::TypefaceRequestExt,
    std::{collections::HashSet, sync::Arc},
};

fn unwrap_query<'a>(query: &'a Option<TypefaceQuery>) -> Result<&'a TypefaceQuery, Error> {
    query.as_ref().ok_or(format_err!("Missing query"))
}

/// Ordered collection of `Typeface`s. Construct using [`TypefaceCollectionBuilder`].
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct Collection {
    /// Some typefaces may be in more than one collection. In particular, fallback typefaces are
    /// added to the family collection and also to the fallback collection.
    pub faces: Vec<Arc<Typeface>>,
}

impl Collection {
    pub fn match_request<'a, 'b>(
        &'a self,
        request: &'b TypefaceRequest,
    ) -> Result<Option<&'a Typeface>, Error> {
        /// Returns true if request does not require an exact style match, _or_ if the query's style
        /// values match those that are in the `typeface`.
        ///
        /// Any style properties that are omitted from the query are ignored.
        fn does_exact_style_match(request: &TypefaceRequest, typeface: &Typeface) -> bool {
            if !request.exact_style() {
                return true;
            }
            let query = request.query.as_ref().unwrap();
            match &query.style {
                None => true,
                Some(style) => {
                    (style.width.is_none() || style.width.unwrap() == typeface.width)
                        && (style.weight.is_none() || style.weight.unwrap() == typeface.weight)
                        && (style.slant.is_none() || style.slant.unwrap() == typeface.slant)
                }
            }
        }

        /// Returns true if there are no code points in the query, or if all of the code points are
        /// present in the `char_set`.
        fn do_code_points_match(char_set: &CharSet, query_code_points: &Option<Vec<u32>>) -> bool {
            match &query_code_points {
                Some(code_points) => {
                    code_points.iter().all(|code_point| char_set.contains(*code_point))
                }
                None => true,
            }
        }

        fn fold<'a, 'b>(
            best: Option<TypefaceAndLangScore<'a>>,
            x: &'a Typeface,
            request: &'b TypefaceRequest,
        ) -> Result<Option<TypefaceAndLangScore<'a>>, Error> {
            let x = TypefaceAndLangScore::new(x, request);
            match best {
                Some(b) => Ok(Some(select_best_match(b, x, unwrap_query(&request.query)?))),
                None => Ok(Some(x)),
            }
        }

        let query = unwrap_query(&request.query)?;

        Ok(self
            .faces
            .iter()
            .filter(|f| does_exact_style_match(&request, f))
            .filter(|f| do_code_points_match(&f.char_set, &query.code_points))
            .try_fold(None, |best, x| fold(best, x, request))?
            .map(|a| a.typeface))
    }

    pub fn get_styles<'a>(&'a self) -> impl Iterator<Item = Style2> + 'a {
        self.faces.iter().map(|f| Style2 {
            width: Some(f.width),
            slant: Some(f.slant),
            weight: Some(f.weight),
            ..Style2::EMPTY
        })
    }
}

/// Builder for [typeface `Collection`](crate::font_service::typeface::Collection).
#[derive(Debug)]
pub struct TypefaceCollectionBuilder {
    faces: Vec<Arc<Typeface>>,
    /// Bookkeeping for deduplication
    seen_ids: HashSet<TypefaceId>,
}

impl TypefaceCollectionBuilder {
    /// Creates a new collection builder with no typefaces.
    pub fn new() -> Self {
        TypefaceCollectionBuilder { faces: vec![], seen_ids: HashSet::new() }
    }

    /// Returns true if the collection already has a typeface with the given ID.
    pub fn has_typeface_id(&self, typeface_id: &TypefaceId) -> bool {
        self.seen_ids.contains(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 {
        let typeface_id = TypefaceId { asset_id: typeface.asset_id, index: typeface.font_index };
        if self.seen_ids.contains(&typeface_id) {
            false
        } else {
            self.seen_ids.insert(typeface_id);
            self.faces.push(typeface);
            true
        }
    }

    /// Returns true if there are no typefaces currently in the collection.
    pub fn is_empty(&self) -> bool {
        self.faces.is_empty()
    }

    /// Creates a `Collection` from the builder's current state. Call this method last, once you are
    /// satisfied with how the collection is configured.
    pub fn build(self) -> Collection {
        Collection { faces: self.faces }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::{super::test_util::*, *},
        crate::font_service::AssetId,
        fidl_fuchsia_fonts::{
            GenericFontFamily, Slant, TypefaceRequestFlags, Width, WEIGHT_LIGHT, WEIGHT_NORMAL,
            WEIGHT_SEMI_BOLD, WEIGHT_THIN,
        },
        manifest::v2,
    };

    fn make_fake_typeface_collection(mut faces: Vec<Typeface>) -> Collection {
        let mut builder = TypefaceCollectionBuilder::new();
        for (i, mut typeface) in faces.drain(..).enumerate() {
            // Assign fake asset_id to each font
            typeface.asset_id = AssetId(i as u32);
            builder.add_typeface_once(Arc::new(typeface));
        }

        builder.build()
    }

    fn make_fake_typeface(
        width: Width,
        slant: Slant,
        weight: u16,
        languages: &[&str],
        char_set: &[u32],
        generic_family: Option<GenericFontFamily>,
    ) -> Typeface {
        // Prevent error if char_set is empty
        let char_set = if char_set.is_empty() { &[0] } else { char_set };
        Typeface::new(
            AssetId(0),
            v2::Typeface {
                index: 0,
                style: v2::Style { slant, weight, width },
                languages: languages.iter().map(|s| s.to_string()).collect(),
                code_points: CharSet::new(char_set.to_vec()),
            },
            generic_family,
        )
        .unwrap() // Safe because char_set is not empty
    }

    fn request_typeface<'a, 'b>(
        collection: &'a Collection,
        width: impl Into<Option<Width>>,
        slant: impl Into<Option<Slant>>,
        weight: impl Into<Option<u16>>,
        languages: impl Into<Option<&'b [&'b str]>>,
        flags: TypefaceRequestFlags,
        fallback_family: impl Into<Option<GenericFontFamily>>,
    ) -> Result<Option<&'a Typeface>, Error> {
        let request =
            make_typeface_request(width, slant, weight, languages, flags, fallback_family);
        collection.match_request(&request)
    }

    fn request_style_exact(
        collection: &Collection,
        width: impl Into<Option<Width>>,
        slant: impl Into<Option<Slant>>,
        weight: impl Into<Option<u16>>,
    ) -> Result<Option<&Typeface>, Error> {
        request_typeface(
            collection,
            width,
            slant,
            weight,
            None,
            TypefaceRequestFlags::ExactStyle,
            None,
        )
    }

    #[test]
    fn test_font_matching_exact() -> Result<(), Error> {
        let collection = make_fake_typeface_collection(vec![
            make_fake_typeface_style(Width::ExtraCondensed, Slant::Upright, WEIGHT_SEMI_BOLD),
            make_fake_typeface_style(Width::Condensed, Slant::Italic, WEIGHT_THIN),
            make_fake_typeface_style(Width::ExtraExpanded, Slant::Oblique, WEIGHT_NORMAL),
        ]);

        assert_eq!(
            request_style_exact(&collection, Width::Condensed, Slant::Italic, WEIGHT_THIN)?
                .ok_or_else(|| format_err!("Exact style not found"))?
                .asset_id,
            AssetId(1)
        );

        assert!(request_style_exact(
            &collection,
            Width::SemiCondensed,
            Slant::Italic,
            WEIGHT_THIN,
        )?
        .is_none());
        assert!(request_style_exact(&collection, Width::Condensed, Slant::Upright, WEIGHT_THIN)?
            .is_none());
        assert!(request_style_exact(&collection, Width::Condensed, Slant::Italic, WEIGHT_LIGHT)?
            .is_none());

        Ok(())
    }

    /// Exact style matches where the query includes only some of the style properties.
    #[test]
    fn test_font_matching_exact_partial() -> Result<(), Error> {
        fn exact_style_not_found() -> Error {
            format_err!("Exact style not found")
        }

        let collection = make_fake_typeface_collection(vec![
            make_fake_typeface_style(Width::ExtraCondensed, Slant::Upright, WEIGHT_SEMI_BOLD),
            make_fake_typeface_style(Width::Condensed, Slant::Italic, WEIGHT_THIN),
            make_fake_typeface_style(Width::ExtraExpanded, Slant::Oblique, WEIGHT_SEMI_BOLD),
            make_fake_typeface_style(Width::ExtraExpanded, Slant::Oblique, WEIGHT_NORMAL),
        ]);

        assert_eq!(
            request_style_exact(&collection, None, None, WEIGHT_THIN)?
                .ok_or_else(exact_style_not_found)?
                .asset_id,
            AssetId(1)
        );

        assert_eq!(
            request_style_exact(&collection, Width::ExtraExpanded, None, None)?
                .ok_or_else(exact_style_not_found)?
                .asset_id,
            AssetId(3)
        );

        assert!(
            request_style_exact(&collection, Width::SemiCondensed, Slant::Oblique, None)?.is_none()
        );

        Ok(())
    }

    fn make_fake_typeface_with_languages(languages: &[&str]) -> Typeface {
        make_fake_typeface(Width::Normal, Slant::Upright, WEIGHT_NORMAL, languages, &[], None)
    }

    fn request_lang<'a, 'b>(
        collection: &'a Collection,
        lang: &'b [&'b str],
    ) -> Result<&'a Typeface, Error> {
        request_typeface(
            collection,
            Width::Normal,
            Slant::Upright,
            WEIGHT_NORMAL,
            Some(lang),
            TypefaceRequestFlags::empty(),
            None,
        )?
        .ok_or_else(|| format_err!("No typeface found for lang"))
    }

    #[test]
    fn test_font_matching_lang() -> Result<(), Error> {
        let collection = make_fake_typeface_collection(vec![
            make_fake_typeface_with_languages(&["a"]),
            make_fake_typeface_with_languages(&["b-C"]),
            make_fake_typeface_with_languages(&["b-D", "b-E"]),
            make_fake_typeface_with_languages(&["fooo"]),
            make_fake_typeface_with_languages(&["foo-BAR"]),
        ]);

        // Exact matches.
        assert_eq!(request_lang(&collection, &["a"])?.asset_id, AssetId(0));
        assert_eq!(request_lang(&collection, &["b-C"])?.asset_id, AssetId(1));
        assert_eq!(request_lang(&collection, &["b-E"])?.asset_id, AssetId(2));

        // Verify that request language order is respected.
        assert_eq!(request_lang(&collection, &["b-C", "a"])?.asset_id, AssetId(1));

        // Partial match: the first matching font is returned first.
        assert_eq!(request_lang(&collection, &["b"])?.asset_id, AssetId(1));

        // Exact match overrides preceding partial match.
        assert_eq!(request_lang(&collection, &["b", "a"])?.asset_id, AssetId(0));

        // Partial match should match a whole BCP47 segment.
        assert_eq!(request_lang(&collection, &["foo"])?.asset_id, AssetId(4));

        Ok(())
    }

    fn make_fake_typeface_with_fallback_family(fallback_family: GenericFontFamily) -> Typeface {
        make_fake_typeface(
            Width::Normal,
            Slant::Upright,
            WEIGHT_NORMAL,
            &[],
            &[],
            Some(fallback_family),
        )
    }

    fn request_fallback_family(
        collection: &Collection,
        fallback_family: GenericFontFamily,
    ) -> Result<&Typeface, Error> {
        request_typeface(
            collection,
            Width::Normal,
            Slant::Upright,
            WEIGHT_NORMAL,
            None,
            TypefaceRequestFlags::empty(),
            Some(fallback_family),
        )?
        .ok_or_else(|| format_err!("No typeface found for fallback family"))
    }

    #[test]
    fn test_font_matching_fallback_group() -> Result<(), Error> {
        let collection = make_fake_typeface_collection(vec![
            make_fake_typeface_with_fallback_family(GenericFontFamily::Serif),
            make_fake_typeface_with_fallback_family(GenericFontFamily::SansSerif),
            make_fake_typeface_with_fallback_family(GenericFontFamily::Monospace),
        ]);

        assert_eq!(
            request_fallback_family(&collection, GenericFontFamily::Serif)?.asset_id,
            AssetId(0)
        );
        assert_eq!(
            request_fallback_family(&collection, GenericFontFamily::SansSerif)?.asset_id,
            AssetId(1)
        );
        assert_eq!(
            request_fallback_family(&collection, GenericFontFamily::Monospace)?.asset_id,
            AssetId(2)
        );

        // First font is returned when there is no exact match.
        assert_eq!(
            request_fallback_family(&collection, GenericFontFamily::Cursive)?.asset_id,
            AssetId(0)
        );

        Ok(())
    }
}
