// =============================================================================
// =ALEKSI - MAP-SORT-KEYS
// =============================================================================
////
//// @group aleksi-maps
//// @author [Yoannis Jamar](https://yoannis.com)

@import "aleksi/general/throw";
@import "aleksi/general/default-to";
@import "aleksi/lists/sort";
@import "aleksi/maps/is-map";

// =map-sort-keys( $map[, $order ])
// -----------------------------------------------------------------------------
/// Orders a map's keys according to a given, ordered list of keys. If no order
/// is specified, the keys will be ordered alphabetically.
/// **Note**: keys that are not in the ordered list will be added at the end of
/// the resulting map, in the same order as in the original map.
///
/// @param {map} $map - The map to order.
/// @param {list} $order (alphabetic order) - An ordered list of key names.
///
/// @return {map|null} - The map with it's keys in the same order as `$order`.
///
/// @throw Error if `$map` is not a map.
/// @throw Error if `$order` is not a list, a string, null or false.
///
/// @access public
/// @since 0.1.0

@function map-sort-keys( $map, $order: null )
{
  @if not is-map($map) {
    @return throw-error('map-sort-keys():: $map must be a map, was #{inspect($map)}.');
  }

  // allow lists and single strings for `$order`
  @if not is-of-type($order, 'list' 'string' 'null') {
    @return throw-error('map-sort-keys():: $order must be a list or a single string. Was #{inspect($order)}.');
  }

  $keys: map-keys($map);
  $order: default-to($order, sort($keys));
  $res: ();

  @each $key in $order {
    @if index($keys, $key) {
      $val: map-get($map, $key);
      $res: map-merge($res, ($key: $val));
    }
  }

  // include leftovers at the end
  @if length($res) < length($map) {
    $res: map-merge($res, $map);
  }

  @return $res;
}

// =map-sort( $map[, $order ])
// -----------------------------------------------------------------------------
/// @alias map-sort-keys
///
/// @access public
/// @since 0.1.0

@function map-sort($map, $order: null)
{
  @return map-sort-keys($map, $order);
}