// 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.

//! Traits for mergeable structs and collections of font metadata.

use {
    anyhow::Error,
    itertools::Itertools,
    std::{fmt::Debug, hash::Hash},
    thiserror::Error,
};

/// Indicates that multiple items that implement this trait should be merged if they all have the
/// same key.
///
/// See [crate::font_catalog::Family] for example.
pub trait TryMerge: Clone + Debug + Eq + Hash + Sync + Send + Sized + 'static {
    type Key: Clone + Hash + Eq + PartialEq + Ord + PartialOrd + 'static;

    /// The key by which to group the items.
    fn key(&self) -> Self::Key;

    /// Returns `true` for two items about to be merged if the fields are expected to match up
    /// between them do in fact match up.
    ///
    /// The default implementation just delegates to `==`, but this can be made narrower.
    ///
    /// Usually, overriders will want to exclude the `key` field and any collection fields that will
    /// be merged.
    fn has_matching_fields(&self, other: &Self) -> bool {
        self == other
    }

    /// Merges a group of items into one. At this point, it has already been confirmed that all the
    /// items in the group have matching fields, as defined by [`has_matching_fields`].
    fn try_merge_group(group: Vec<Self>) -> Result<Self, Error>;

    /// Perform validation on the entire set of merged groups.
    ///
    /// The default implementation is a no-op.
    fn post_validate(groups: Vec<Self>) -> Result<Vec<Self>, MergeError<Self>> {
        Ok(groups)
    }
}

/// Try to merge multiple items into a single one. If there are any inconsistencies in the
/// fields that are expected to be identical, an error will be returned.
fn try_match_fields_and_merge_group<T>(group: impl IntoIterator<Item = T>) -> Result<T, Error>
where
    T: TryMerge,
{
    let group: Vec<T> = group.into_iter().collect();

    if !all_have_matching_fields(&group) {
        Err(MergeError::Conflict(group).into())
    } else {
        TryMerge::try_merge_group(group)
    }
}

/// Returns true if all the items in the given group return `true` for
/// [`TryMerge::has_matching_fields`] when compared to the first item in the group.
fn all_have_matching_fields<T>(group: &Vec<T>) -> bool
where
    T: TryMerge,
{
    let mut iter = group.iter();
    let first = iter.next();
    if first.is_none() {
        true
    } else {
        let first = first.unwrap();
        iter.all(|item| item.has_matching_fields(first))
    }
}

/// Import this trait to allow the use of [`TryMergeGroups::try_merge_groups`] on an `Iterator`.
pub trait TryMergeGroups
where
    Self: Iterator + Sized,
    Self::Item: TryMerge,
{
    /// For an iterator over a list of items with possible duplicates or mergeable items, removes
    /// duplicates, attempts to merge overlapping items, and sorts by the items' keys.
    fn try_merge_groups(self) -> Result<Vec<Self::Item>, Error> {
        let merged: Result<Vec<Self::Item>, _> = self
            .unique()
            .map(|item| (item.key(), item))
            .into_group_map()
            .into_iter()
            .map(|(_key, items)| try_match_fields_and_merge_group(items))
            .collect();

        let mut merged = merged?;
        merged.sort_by_key(|item| item.key());
        TryMerge::post_validate(merged).map_err(|e| e.into())
    }
}

/// Blanket implementation of `TryMergeGroups`.
impl<T, V> TryMergeGroups for T
where
    T: Iterator<Item = V>,
    V: TryMerge,
{
}

/// Errors while merging a group of items.
#[derive(Debug, Error)]
pub enum MergeError<V>
where
    V: Debug + Send + Sync + 'static,
{
    #[error("Conflict when attempting to merge {:?}", _0)]
    Conflict(Vec<V>),
    #[error("Post validation failed with [{}] on list {:?}", _0, _1)]
    PostInvalid(String, Vec<V>),
}
