/**
 * 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.tools.rumen;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.ArrayList;
import java.util.Comparator;

import org.codehaus.jackson.annotate.JsonAnySetter;

/**
 * A {@link LoggedNetworkTopology} represents a tree that in turn represents a
 * hierarchy of hosts. The current version requires the tree to have all leaves
 * at the same level.
 * 
 * All of the public methods are simply accessors for the instance variables we
 * want to write out in the JSON files.
 * 
 */
public class LoggedNetworkTopology implements DeepCompare {
  String name;
  List<LoggedNetworkTopology> children = new ArrayList<LoggedNetworkTopology>();

  static private Set<String> alreadySeenAnySetterAttributes =
      new TreeSet<String>();

  public LoggedNetworkTopology() {
    super();
  }

  @SuppressWarnings("unused")
  // for input parameter ignored.
  @JsonAnySetter
  public void setUnknownAttribute(String attributeName, Object ignored) {
    if (!alreadySeenAnySetterAttributes.contains(attributeName)) {
      alreadySeenAnySetterAttributes.add(attributeName);
      System.err.println("In LoggedJob, we saw the unknown attribute "
          + attributeName + ".");
    }
  }

  /**
   * We need this because we have to sort the {@code children} field. That field
   * is set-valued, but if we sort these fields we ensure that comparisons won't
   * bogusly fail because the hash table happened to enumerate in a different
   * order.
   * 
   */
  static class TopoSort implements Comparator<LoggedNetworkTopology> {
    public int compare(LoggedNetworkTopology t1, LoggedNetworkTopology t2) {
      return t1.name.compareTo(t2.name);
    }
  }

  /**
   * @param hosts
   *          a HashSet of the {@link ParsedHost}
   * @param name
   *          the name of this level's host [for recursive descent]
   * @param level
   *          the level number
   */
  LoggedNetworkTopology(Set<ParsedHost> hosts, String name, int level) {

    this.name = name;
    this.children = null;

    if (level < ParsedHost.numberOfDistances() - 1) {
      HashMap<String, HashSet<ParsedHost>> topologies =
          new HashMap<String, HashSet<ParsedHost>>();

      Iterator<ParsedHost> iter = hosts.iterator();

      while (iter.hasNext()) {
        ParsedHost host = iter.next();

        String thisComponent = host.nameComponent(level);

        HashSet<ParsedHost> thisSet = topologies.get(thisComponent);

        if (thisSet == null) {
          thisSet = new HashSet<ParsedHost>();
          topologies.put(thisComponent, thisSet);
        }

        thisSet.add(host);
      }

      children = new ArrayList<LoggedNetworkTopology>();

      for (Map.Entry<String, HashSet<ParsedHost>> ent : topologies.entrySet()) {
        children.add(new LoggedNetworkTopology(ent.getValue(), ent.getKey(),
            level + 1));
      }
    } else {
      // nothing to do here
    }
  }

  LoggedNetworkTopology(Set<ParsedHost> hosts) {
    this(hosts, "<root>", 0);
  }

  public String getName() {
    return name;
  }

  void setName(String name) {
    this.name = name;
  }

  public List<LoggedNetworkTopology> getChildren() {
    return children;
  }

  void setChildren(List<LoggedNetworkTopology> children) {
    this.children = children;
  }

  private void compare1(List<LoggedNetworkTopology> c1,
      List<LoggedNetworkTopology> c2, TreePath loc, String eltname)
      throws DeepInequalityException {
    if (c1 == null && c2 == null) {
      return;
    }

    if (c1 == null || c2 == null || c1.size() != c2.size()) {
      throw new DeepInequalityException(eltname + " miscompared", new TreePath(
          loc, eltname));
    }

    Collections.sort(c1, new TopoSort());
    Collections.sort(c2, new TopoSort());

    for (int i = 0; i < c1.size(); ++i) {
      c1.get(i).deepCompare(c2.get(i), new TreePath(loc, eltname, i));
    }
  }

  public void deepCompare(DeepCompare comparand, TreePath loc)
      throws DeepInequalityException {
    if (!(comparand instanceof LoggedNetworkTopology)) {
      throw new DeepInequalityException("comparand has wrong type", loc);
    }

    LoggedNetworkTopology other = (LoggedNetworkTopology) comparand;

    compare1(children, other.children, loc, "children");
  }
}
