/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

export class SortUtils {
  public static statusSort(arg1: string, arg2: string): number {
    const order = ['creating', 'running', 'stopping', 'stopped', 'terminating', 'terminated', 'failed'];

    return order.indexOf(arg1) - order.indexOf(arg2);
  }

  public static activeStatuses(): String[] {
    return ['running', 'stopping', 'stopped', 'creating', 'configuring', 'reconfiguring', 'starting', 'creating image'];
  }

  public static shapesSort(shapesJson) {
    const sortOrder = ['For testing', 'Memory optimized', 'GPU optimized', 'Compute optimized'];
    const sortedShapes = {};

    Object.keys(shapesJson)
      .sort((a, b) => sortOrder.indexOf(a) - sortOrder.indexOf(b))
      .forEach(key => {
        if (shapesJson[key].length) {
          sortedShapes[key] = shapesJson[key];
        }
      });

    return sortedShapes;
  }

  public static libGroupsSort(groups) {
    const sortOrder = ['os_pkg', 'pip3', 'r_pkg', 'java', 'others'];

    return groups.sort((arg1, arg2) => sortOrder.indexOf(arg1) - sortOrder.indexOf(arg2));
  }

  public static libFilterGroupsSort(groups) {
    const sortOrder = ['Apt/Yum', 'Python 3', 'R packages', 'Java', 'Others'];

    return groups.sort((arg1, arg2) => sortOrder.indexOf(arg1) - sortOrder.indexOf(arg2));
  }

  public static flatDeep(arr, d = 1) {
    return d > 0 
      ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? this.flatDeep(val, d - 1) : val), [])
      : arr.slice();
  }

  public static sortByKeys(array, keys) {
    keys.forEach(key => {
      array = array.sort((a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0));
    });
    return array;
  }

}
