@use 'sass:map';
@use 'sass:meta';
@use '@angular/material' as mat;
@use './mtx/alert' as tokens-mtx-alert;
@use './mtx/colorpicker' as tokens-mtx-colorpicker;
@use './mtx/datetimepicker' as tokens-mtx-datetimepicker;
@use './mtx/drawer' as tokens-mtx-drawer;
@use './mtx/grid' as tokens-mtx-grid;
@use './mtx/loader' as tokens-mtx-loader;
@use './mtx/popover' as tokens-mtx-popover;
@use './mtx/progress' as tokens-mtx-progress;
@use './mtx/select' as tokens-mtx-select;
@use './mtx/split' as tokens-mtx-split;

/// Gets the tokens for the given theme, m2 tokens module, and theming system.
/// @param {Map} $theme The Angular Material theme object to generate token values from.
/// @param {String} $module The Sass module containing the token getter functions.
/// @param {String} $system The theming system to get tokens for. Valid values are: unthemable,
///     color, typography, density.
/// @return {Map} The token map by calling the token getter for the given system in the given module
///    with the given Angular Material theme. Token names are not fully-qualified.
@function _get-tokens-for-module-and-system($theme, $module, $system) {
  @if $system == unthemable {
    @return meta.call(
        meta.get-function(get-#{$system}-tokens, $module: $module));
  }
  @if not mat.theme-has($theme, $system) {
    @return ();
  }
  @return meta.call(
      meta.get-function(get-#{$system}-tokens, $module: $module), $theme);
}

/// Gets the fully qualified tokens map for the given theme and m2 tokens module.
/// @param {Map} $theme The Angular Material theme object to generate token values from.
/// @param {String} $module The Sass module containing the token getter functions.
/// @return {Map} The token map by calling the token getters in the given module with the given
///     Angular Material theme. Token names are fully-qualified.
@function _get-tokens-for-module($theme, $module) {
  $tokens: mat.private-deep-merge-all(
      _get-tokens-for-module-and-system($theme, $module, unthemable),
      _get-tokens-for-module-and-system($theme, $module, color),
      _get-tokens-for-module-and-system($theme, $module, typography),
      _get-tokens-for-module-and-system($theme, $module, density));
  @return map.set((), map.get(meta.module-variables($module), prefix), $tokens);
}

/// Gets the full set of M2 tokens for the given theme object.
/// @param {Map} $theme The Angular Material theme object to generate token values from.
/// @return {Map} The token map for the given Angular Material theme. Returned format:
///     (
///       (fully, qualified, namespace): (
///         token: value
///       )
///     )
@function m2-tokens-from-theme($theme) {
  @return mat.private-deep-merge-all(
    _get-tokens-for-module($theme, tokens-mtx-alert),
    _get-tokens-for-module($theme, tokens-mtx-colorpicker),
    _get-tokens-for-module($theme, tokens-mtx-datetimepicker),
    _get-tokens-for-module($theme, tokens-mtx-drawer),
    _get-tokens-for-module($theme, tokens-mtx-grid),
    _get-tokens-for-module($theme, tokens-mtx-loader),
    _get-tokens-for-module($theme, tokens-mtx-popover),
    _get-tokens-for-module($theme, tokens-mtx-progress),
    _get-tokens-for-module($theme, tokens-mtx-select),
    _get-tokens-for-module($theme, tokens-mtx-split),
  );
}
