/**
 * 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.
 */
package org.apache.hadoop.hdds.scm.net;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Utility class to facilitate network topology functions.
 */
public final class NetUtils {
  public static final Logger LOG = LoggerFactory.getLogger(NetUtils.class);
  private NetUtils() {
    // Prevent instantiation
  }
  /**
   * Normalize a path by stripping off any trailing.
   * {@link NetConstants#PATH_SEPARATOR}
   * @param path path to normalize.
   * @return the normalised path
   * If <i>path</i>is empty or null, then {@link NetConstants#ROOT} is returned
   */
  public static String normalize(String path) {
    if (path == null || path.length() == 0) {
      return NetConstants.ROOT;
    }

    if (path.charAt(0) != NetConstants.PATH_SEPARATOR) {
      throw new IllegalArgumentException(
          "Network Location path does not start with "
              + NetConstants.PATH_SEPARATOR_STR + ": " + path);
    }

    // Remove any trailing NetConstants.PATH_SEPARATOR
    return path.length() == 1 ? path :
        path.replaceAll(NetConstants.PATH_SEPARATOR_STR + "+$", "");
  }

  /**
   *  Given a network topology location string, return its network topology
   *  depth, E.g. the depth of /dc1/rack1/ng1/node1 is 5.
   */
  public static int locationToDepth(String location) {
    String newLocation = normalize(location);
    return newLocation.equals(NetConstants.PATH_SEPARATOR_STR) ? 1 :
        newLocation.split(NetConstants.PATH_SEPARATOR_STR).length;
  }


  /**
   *  Remove node from mutableExcludedNodes if it's covered by excludedScope.
   *  Please noted that mutableExcludedNodes content might be changed after the
   *  function call.
   */
  public static void removeDuplicate(NetworkTopology topology,
      Collection<Node> mutableExcludedNodes, List<String> mutableExcludedScopes,
      int ancestorGen) {
    if (CollectionUtils.isEmpty(mutableExcludedNodes) ||
        CollectionUtils.isEmpty(mutableExcludedScopes) || topology == null) {
      return;
    }

    Iterator<Node> iterator = mutableExcludedNodes.iterator();
    while (iterator.hasNext() && (!mutableExcludedScopes.isEmpty())) {
      Node node = iterator.next();
      Node ancestor = topology.getAncestor(node, ancestorGen);
      if (ancestor == null) {
        LOG.warn("Fail to get ancestor generation " + ancestorGen +
            " of node :" + node);
        continue;
      }
      // excludedScope is child of ancestor
      List<String> duplicateList = mutableExcludedScopes.stream()
          .filter(scope -> scope.startsWith(ancestor.getNetworkFullPath()))
          .collect(Collectors.toList());
      mutableExcludedScopes.removeAll(duplicateList);

      // ancestor is covered by excludedScope
      mutableExcludedScopes.stream().forEach(scope -> {
        if (ancestor.getNetworkFullPath().startsWith(scope)) {
          // remove exclude node if it's covered by excludedScope
          iterator.remove();
        }
      });
    }
  }

  /**
   *  Remove node from mutableExcludedNodes if it's not part of scope
   *  Please noted that mutableExcludedNodes content might be changed after the
   *  function call.
   */
  public static void removeOutscope(Collection<Node> mutableExcludedNodes,
      String scope) {
    if (CollectionUtils.isEmpty(mutableExcludedNodes) || scope == null) {
      return;
    }
    synchronized (mutableExcludedNodes) {
      Iterator<Node> iterator = mutableExcludedNodes.iterator();
      while (iterator.hasNext()) {
        Node next = iterator.next();
        if (!next.getNetworkFullPath().startsWith(scope)) {
          iterator.remove();
        }
      }
    }
  }

  /**
   * Get a ancestor list for nodes on generation <i>generation</i>.
   *
   * @param nodes a collection of leaf nodes
   * @param generation  the ancestor generation
   * @return the ancestor list. If no ancestor is found, then a empty list is
   * returned.
   */
  public static List<Node> getAncestorList(NetworkTopology topology,
      Collection<Node> nodes, int generation) {
    List<Node> ancestorList = new ArrayList<>();
    if (topology == null || CollectionUtils.isEmpty(nodes) ||
        generation == 0) {
      return ancestorList;
    }
    Iterator<Node> iterator = nodes.iterator();
    while (iterator.hasNext()) {
      Node node = iterator.next();
      Node ancestor = topology.getAncestor(node, generation);
      if (ancestor == null) {
        LOG.warn("Fail to get ancestor generation " + generation +
            " of node :" + node);
        continue;
      }
      if (!ancestorList.contains(ancestor)) {
        ancestorList.add(ancestor);
      }
    }
    return ancestorList;
  }
}
