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

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.commons.logging.*;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableUtils;
import org.apache.hadoop.mapreduce.CounterGroup;
import org.apache.hadoop.util.StringUtils;

/**
 * A set of named counters.
 * 
 * <p><code>Counters</code> represent global counters, defined either by the 
 * Map-Reduce framework or applications. Each <code>Counter</code> can be of
 * any {@link Enum} type.</p>
 * 
 * <p><code>Counters</code> are bunched into {@link Group}s, each comprising of
 * counters from a particular <code>Enum</code> class. 
 */
public class Counters implements Writable, Iterable<Counters.Group> {
  private static final Log LOG = LogFactory.getLog(Counters.class);
  private static final char GROUP_OPEN = '{';
  private static final char GROUP_CLOSE = '}';
  private static final char COUNTER_OPEN = '[';
  private static final char COUNTER_CLOSE = ']';
  private static final char UNIT_OPEN = '(';
  private static final char UNIT_CLOSE = ')';
  private static char[] charsToEscape =  {GROUP_OPEN, GROUP_CLOSE, 
                                          COUNTER_OPEN, COUNTER_CLOSE, 
                                          UNIT_OPEN, UNIT_CLOSE};
  private static final JobConf conf = new JobConf();
  /** limit on the size of the name of the group **/
  private static final int GROUP_NAME_LIMIT = 
    conf.getInt("mapreduce.job.counters.group.name.max", 128);
  /** limit on the size of the counter name **/
  private static final int COUNTER_NAME_LIMIT = 
    conf.getInt("mapreduce.job.counters.counter.name.max", 64);
  
  /** limit on counters **/
  public static int MAX_COUNTER_LIMIT = 
    conf.getInt("mapreduce.job.counters.limit", // deprecated in 0.23
        conf.getInt("mapreduce.job.counters.max", 120));

  /** the max groups allowed **/
  public static final int MAX_GROUP_LIMIT = 
    conf.getInt("mapreduce.job.counters.groups.max", 50);
  
  /** the number of current counters**/
  private int numCounters = 0;

  //private static Log log = LogFactory.getLog("Counters.class");
  
  /**
   * A counter record, comprising its name and value. 
   */
  public static class Counter extends org.apache.hadoop.mapreduce.Counter {
    
    Counter() { 
    }

    Counter(String name, String displayName, long value) {
      super(name, displayName);
      increment(value);
    }
    
    public void setDisplayName(String newName) {
      super.setDisplayName(newName);
    }
    
    /**
     * Returns the compact stringified version of the counter in the format
     * [(actual-name)(display-name)(value)]
     */
    public synchronized String makeEscapedCompactString() {

      // First up, obtain the strings that need escaping. This will help us
      // determine the buffer length apriori.
      String escapedName = escape(getName());
      String escapedDispName = escape(getDisplayName());
      long currentValue = this.getValue();
      int length = escapedName.length() + escapedDispName.length() + 4;

      length += 8; // For the following delimiting characters
      StringBuilder builder = new StringBuilder(length);
      builder.append(COUNTER_OPEN);
      
      // Add the counter name
      builder.append(UNIT_OPEN);
      builder.append(escapedName);
      builder.append(UNIT_CLOSE);
      
      // Add the display name
      builder.append(UNIT_OPEN);
      builder.append(escapedDispName);
      builder.append(UNIT_CLOSE);
      
      // Add the value
      builder.append(UNIT_OPEN);
      builder.append(currentValue);
      builder.append(UNIT_CLOSE);
      
      builder.append(COUNTER_CLOSE);
      
      return builder.toString();
    }
    
    // Checks for (content) equality of two (basic) counters
    synchronized boolean contentEquals(Counter c) {
      return this.equals(c);
    }
    
    /**
     * What is the current value of this counter?
     * @return the current value
     */
    public synchronized long getCounter() {
      return getValue();
    }
    
  }
  
  /**
   *  <code>Group</code> of counters, comprising of counters from a particular 
   *  counter {@link Enum} class.  
   *
   *  <p><code>Group</code>handles localization of the class name and the 
   *  counter names.</p>
   */
  public class Group implements Writable, Iterable<Counter> {
    private String groupName;
    private String displayName;
    private Map<String, Counter> subcounters = new HashMap<String, Counter>();
    
    // Optional ResourceBundle for localization of group and counter names.
    private ResourceBundle bundle = null;    
    
    Group(String groupName) {
      try {
        bundle = CounterGroup.getResourceBundle(groupName);
      }
      catch (MissingResourceException neverMind) {
      }
      this.groupName = groupName;
      this.displayName = localize("CounterGroupName", groupName);
      if (LOG.isDebugEnabled()) {
        LOG.debug("Creating group " + groupName + " with " +
               (bundle == null ? "nothing" : "bundle"));
      }
    }
        
    /**
     * Returns raw name of the group.  This is the name of the enum class
     * for this group of counters.
     */
    public String getName() {
      return groupName;
    }
    
    /**
     * Returns localized name of the group.  This is the same as getName() by
     * default, but different if an appropriate ResourceBundle is found.
     */
    public String getDisplayName() {
      return displayName;
    }
    
    /**
     * Set the display name
     */
    public void setDisplayName(String displayName) {
      this.displayName = displayName;
    }
    
    /**
     * Returns the compact stringified version of the group in the format
     * {(actual-name)(display-name)(value)[][][]} where [] are compact strings for the
     * counters within.
     */
    public String makeEscapedCompactString() {
      String[] subcountersArray = new String[subcounters.size()];

      // First up, obtain the strings that need escaping. This will help us
      // determine the buffer length apriori.
      String escapedName = escape(getName());
      String escapedDispName = escape(getDisplayName());
      int i = 0;
      int length = escapedName.length() + escapedDispName.length();
      for (Counter counter : subcounters.values()) {
        String escapedStr = counter.makeEscapedCompactString();
        subcountersArray[i++] = escapedStr;
        length += escapedStr.length();
      }

      length += 6; // for all the delimiting characters below
      StringBuilder builder = new StringBuilder(length);
      builder.append(GROUP_OPEN); // group start
      
      // Add the group name
      builder.append(UNIT_OPEN);
      builder.append(escapedName);
      builder.append(UNIT_CLOSE);
      
      // Add the display name
      builder.append(UNIT_OPEN);
      builder.append(escapedDispName);
      builder.append(UNIT_CLOSE);
      
      // write the value
      for(String str : subcountersArray) {
        builder.append(str);
      }
      
      builder.append(GROUP_CLOSE); // group end
      return builder.toString();
    }

    @Override
    public int hashCode() {
      return subcounters.hashCode();
    }

    /** 
     * Checks for (content) equality of Groups
     */
    @Override
    public synchronized boolean equals(Object obj) {
      boolean isEqual = false;
      if (obj != null && obj instanceof Group) {
        Group g = (Group) obj;
        if (size() == g.size()) {
          isEqual = true;
          for (Map.Entry<String, Counter> entry : subcounters.entrySet()) {
            String key = entry.getKey();
            Counter c1 = entry.getValue();
            Counter c2 = g.getCounterForName(key);
            if (!c1.contentEquals(c2)) {
              isEqual = false;
              break;
            }
          }
        }
      }
      return isEqual;
    }
    
    /**
     * Returns the value of the specified counter, or 0 if the counter does
     * not exist.
     */
    public synchronized long getCounter(String counterName) {
      for(Counter counter: subcounters.values()) {
        if (counter != null && counter.getDisplayName().equals(counterName)) {
          return counter.getValue();
        }
      }
      return 0L;
    }
    
    /**
     * Get the counter for the given id and create it if it doesn't exist.
     * @param id the numeric id of the counter within the group
     * @param name the internal counter name
     * @return the counter
     * @deprecated use {@link #getCounter(String)} instead
     */
    @Deprecated
    public Counter getCounter(int id, String name) {
      return getCounterForName(name);
    }
    
    /**
     * Get the counter for the given name and create it if it doesn't exist.
     * @param name the internal counter name
     * @return the counter
     */
    public Counter getCounterForName(String name) {
      synchronized(Counters.this) { // lock ordering: Counters then Group
        synchronized (this) {
          String shortName = getShortName(name, COUNTER_NAME_LIMIT);
          Counter result = subcounters.get(shortName);
          if (result == null) {
            if (LOG.isDebugEnabled()) {
              LOG.debug("Adding " + shortName);
            }
            numCounters = (numCounters == 0) ? Counters.this.size(): numCounters; 
            if (numCounters >= MAX_COUNTER_LIMIT) {
              throw new CountersExceededException("Error: Exceeded limits on number of counters - " 
                  + "Counters=" + numCounters + " Limit=" + MAX_COUNTER_LIMIT);
            }
            result = new Counter(shortName, localize(shortName + ".name", shortName), 0L);
            subcounters.put(shortName, result);
            numCounters++;
          }
          return result;
        }
      }
    }
    
    /**
     * Returns the number of counters in this group.
     */
    public synchronized int size() {
      return subcounters.size();
    }
    
    /**
     * Looks up key in the ResourceBundle and returns the corresponding value.
     * If the bundle or the key doesn't exist, returns the default value.
     */
    private String localize(String key, String defaultValue) {
      String result = defaultValue;
      if (bundle != null) {
        try {
          result = bundle.getString(key);
        }
        catch (MissingResourceException mre) {
        }
      }
      return result;
    }
    
    public synchronized void write(DataOutput out) throws IOException {
      Text.writeString(out, displayName);
      WritableUtils.writeVInt(out, subcounters.size());
      for(Counter counter: subcounters.values()) {
        counter.write(out);
      }
    }
    
    public synchronized void readFields(DataInput in) throws IOException {
      displayName = Text.readString(in);
      subcounters.clear();
      int size = WritableUtils.readVInt(in);
      for(int i=0; i < size; i++) {
        Counter counter = new Counter();
        counter.readFields(in);
        subcounters.put(counter.getName(), counter);
      }
    }

    public synchronized Iterator<Counter> iterator() {
      return new ArrayList<Counter>(subcounters.values()).iterator();
    }
  }
  
  // Map from group name (enum class name) to map of int (enum ordinal) to
  // counter record (name-value pair).
  private Map<String,Group> counters = new HashMap<String, Group>();

  /**
   * A cache from enum values to the associated counter. Dramatically speeds up
   * typical usage.
   */
  private Map<Enum, Counter> cache = new IdentityHashMap<Enum, Counter>();

  /**
   * Returns the names of all counter classes.
   * @return Set of counter names.
   */
  public synchronized Collection<String> getGroupNames() {
    return counters.keySet();
  }

  public synchronized Iterator<Group> iterator() {
    return counters.values().iterator();
  }

  /**
   * Returns the named counter group, or an empty group if there is none
   * with the specified name.
   */
  public synchronized Group getGroup(String groupName) {
    String shortGroupName = getShortName(groupName, GROUP_NAME_LIMIT);
    Group result = counters.get(shortGroupName);
    if (result == null) {
      /** check if we have exceeded the max number on groups **/
      if (counters.size() > MAX_GROUP_LIMIT) {
        throw new RuntimeException(
            "Error: Exceeded limits on number of groups in counters - " +
            "Groups=" + counters.size() +" Limit=" + MAX_GROUP_LIMIT);
      }
      result = new Group(shortGroupName);
      counters.put(shortGroupName, result);
    }
    return result;
  } 

  /**
   * Find the counter for the given enum. The same enum will always return the
   * same counter.
   * @param key the counter key
   * @return the matching counter object
   */
  public synchronized Counter findCounter(Enum key) {
    Counter counter = cache.get(key);
    if (counter == null) {
      Group group = getGroup(key.getDeclaringClass().getName());
      if (group != null) {
        counter = group.getCounterForName(key.toString());
        if (counter != null)  cache.put(key, counter);
      }
    }
    return counter;    
  }

  /**
   * Find a counter given the group and the name.
   * @param group the name of the group
   * @param name the internal name of the counter
   * @return the counter for that name
   */
  public synchronized Counter findCounter(String group, String name) {
    Group retGroup = getGroup(group);
    return (retGroup == null) ? null: retGroup.getCounterForName(name);
  }

  /** 
   * Find a counter by using strings
   * @param group the name of the group
   * @param id the id of the counter within the group (0 to N-1)
   * @param name the internal name of the counter
   * @return the counter for that name
   * @deprecated
   */
  @Deprecated
  public synchronized Counter findCounter(String group, int id, String name) {
    Group retGroup = getGroup(group);
    return (retGroup == null) ? null: retGroup.getCounterForName(name);
  }

  /**
   * Increments the specified counter by the specified amount, creating it if
   * it didn't already exist.
   * @param key identifies a counter
   * @param amount amount by which counter is to be incremented
   */
  public synchronized void incrCounter(Enum key, long amount) {
    findCounter(key).increment(amount);
  }
  
  /**
   * Increments the specified counter by the specified amount, creating it if
   * it didn't already exist.
   * @param group the name of the group
   * @param counter the internal name of the counter
   * @param amount amount by which counter is to be incremented
   */
  public synchronized void incrCounter(String group, String counter, long amount) {
    Group retGroup = getGroup(group);
    if (retGroup != null) {
      Counter retCounter = retGroup.getCounterForName(counter);
      if (retCounter != null ) {
        retCounter.increment(amount);
      }
    }
  }
  
  /**
   * Returns current value of the specified counter, or 0 if the counter
   * does not exist.
   */
  public synchronized long getCounter(Enum key) {
    Counter retCounter = findCounter(key);
    return (retCounter == null) ? 0 : retCounter.getValue();
  }
  
  /**
   * Increments multiple counters by their amounts in another Counters 
   * instance.
   * @param other the other Counters instance
   */
  public synchronized void incrAllCounters(Counters other) {
    for (Group otherGroup: other) {
      Group group = getGroup(otherGroup.getName());
      if (group == null) {
        continue;
      }
      group.displayName = otherGroup.displayName;
      for (Counter otherCounter : otherGroup) {
        Counter counter = group.getCounterForName(otherCounter.getName());
        if (counter == null) {
          continue;
        }
        counter.setDisplayName(otherCounter.getDisplayName());
        counter.increment(otherCounter.getValue());
      }
    }
  }

  /**
   * Convenience method for computing the sum of two sets of counters.
   */
  public static Counters sum(Counters a, Counters b) {
    Counters counters = new Counters();
    counters.incrAllCounters(a);
    counters.incrAllCounters(b);
    return counters;
  }
  
  /**
   * Returns the total number of counters, by summing the number of counters
   * in each group.
   */
  public synchronized  int size() {
    int result = 0;
    for (Group group : this) {
      result += group.size();
    }
    return result;
  }
  
  /**
   * Write the set of groups.
   * The external format is:
   *     #groups (groupName group)*
   *
   * i.e. the number of groups followed by 0 or more groups, where each 
   * group is of the form:
   *
   *     groupDisplayName #counters (false | true counter)*
   *
   * where each counter is of the form:
   *
   *     name (false | true displayName) value
   */
  public synchronized void write(DataOutput out) throws IOException {
    out.writeInt(counters.size());
    for (Group group: counters.values()) {
      Text.writeString(out, group.getName());
      group.write(out);
    }
  }
  
  /**
   * Read a set of groups.
   */
  public synchronized void readFields(DataInput in) throws IOException {
    int numClasses = in.readInt();
    counters.clear();
    while (numClasses-- > 0) {
      String groupName = Text.readString(in);
      Group group = new Group(groupName);
      group.readFields(in);
      counters.put(groupName, group);
    }
  }
  
  /**
   * Logs the current counter values.
   * @param log The log to use.
   */
  public void log(Log log) {
    log.info("Counters: " + size());
    for(Group group: this) {
      log.info("  " + group.getDisplayName());
      for (Counter counter: group) {
        log.info("    " + counter.getDisplayName() + "=" + 
                 counter.getCounter());
      }   
    }
  }
  
  /**
   * Return textual representation of the counter values.
   */
  public synchronized String toString() {
    StringBuilder sb = new StringBuilder("Counters: " + size());
    for (Group group: this) {
      sb.append("\n\t" + group.getDisplayName());
      for (Counter counter: group) {
        sb.append("\n\t\t" + counter.getDisplayName() + "=" + 
                  counter.getCounter());
      }
    }
    return sb.toString();
  }

  /**
   * Convert a counters object into a single line that is easy to parse.
   * @return the string with "name=value" for each counter and separated by ","
   */
  public synchronized String makeCompactString() {
    StringBuffer buffer = new StringBuffer();
    boolean first = true;
    for(Group group: this){   
      for(Counter counter: group) {
        if (first) {
          first = false;
        } else {
          buffer.append(',');
        }
        buffer.append(group.getDisplayName());
        buffer.append('.');
        buffer.append(counter.getDisplayName());
        buffer.append(':');
        buffer.append(counter.getCounter());
      }
    }
    return buffer.toString();
  }
  
  /**
   * Represent the counter in a textual format that can be converted back to 
   * its object form
   * @return the string in the following format
   * {(groupname)(group-displayname)[(countername)(displayname)(value)][][]}{}{}
   */
  public synchronized String makeEscapedCompactString() {
    String[] groupsArray = new String[counters.size()];
    int i = 0;
    int length = 0;

    // First up, obtain the escaped string for each group so that we can
    // determine the buffer length apriori.
    for (Group group : this) {
      String escapedString = group.makeEscapedCompactString();
      groupsArray[i++] = escapedString;
      length += escapedString.length();
    }

    // Now construct the buffer
    StringBuilder builder = new StringBuilder(length);
    for (String group : groupsArray) {
      builder.append(group);
    }
    return builder.toString();
  }
  
  /**
   * return the short name of a counter/group name
   * truncates from beginning.
   * @param name the name of a group or counter
   * @param limit the limit of characters
   * @return the short name
   */
  static String getShortName(String name, int limit) {
    return (name.length() > limit ?
          name.substring(name.length() - limit, name.length()): name);
  }

  // Extracts a block (data enclosed within delimeters) ignoring escape 
  // sequences. Throws ParseException if an incomplete block is found else 
  // returns null.
  private static String getBlock(String str, char open, char close, 
                                IntWritable index) throws ParseException {
    StringBuilder split = new StringBuilder();
    int next = StringUtils.findNext(str, open, StringUtils.ESCAPE_CHAR, 
                                    index.get(), split);
    split.setLength(0); // clear the buffer
    if (next >= 0) {
      ++next; // move over '('
      
      next = StringUtils.findNext(str, close, StringUtils.ESCAPE_CHAR, 
                                   next, split);
      if (next >= 0) {
        ++next; // move over ')'
        index.set(next);
        return split.toString(); // found a block
      } else {
        throw new ParseException("Unexpected end of block", next);
      }
    }
    return null; // found nothing
  }
  
  /**
   * Convert a stringified counter representation into a counter object. Note 
   * that the counter can be recovered if its stringified using 
   * {@link #makeEscapedCompactString()}. 
   * @return a Counter
   */
  public static Counters fromEscapedCompactString(String compactString) 
  throws ParseException {
    Counters counters = new Counters();
    IntWritable index = new IntWritable(0);
    
    // Get the group to work on
    String groupString = 
      getBlock(compactString, GROUP_OPEN, GROUP_CLOSE, index);
    
    while (groupString != null) {
      IntWritable groupIndex = new IntWritable(0);
      
      // Get the actual name
      String groupName = 
        getBlock(groupString, UNIT_OPEN, UNIT_CLOSE, groupIndex);
      groupName = unescape(groupName);
      
      // Get the display name
      String groupDisplayName = 
        getBlock(groupString, UNIT_OPEN, UNIT_CLOSE, groupIndex);
      groupDisplayName = unescape(groupDisplayName);
      
      // Get the counters
      Group group = counters.getGroup(groupName);
      group.setDisplayName(groupDisplayName);
      
      String counterString = 
        getBlock(groupString, COUNTER_OPEN, COUNTER_CLOSE, groupIndex);
      
      while (counterString != null) {
        IntWritable counterIndex = new IntWritable(0);
        
        // Get the actual name
        String counterName = 
          getBlock(counterString, UNIT_OPEN, UNIT_CLOSE, counterIndex);
        counterName = unescape(counterName);
        
        // Get the display name
        String counterDisplayName = 
          getBlock(counterString, UNIT_OPEN, UNIT_CLOSE, counterIndex);
        counterDisplayName = unescape(counterDisplayName);
        
        // Get the value
        long value = 
          Long.parseLong(getBlock(counterString, UNIT_OPEN, UNIT_CLOSE, 
                                  counterIndex));
        
        // Add the counter
        Counter counter = group.getCounterForName(counterName);
        counter.setDisplayName(counterDisplayName);
        counter.increment(value);
        
        // Get the next counter
        counterString = 
          getBlock(groupString, COUNTER_OPEN, COUNTER_CLOSE, groupIndex);
      }
      
      groupString = getBlock(compactString, GROUP_OPEN, GROUP_CLOSE, index);
    }
    return counters;
  }

  // Escapes all the delimiters for counters i.e {,[,(,),],}
  private static String escape(String string) {
    return StringUtils.escapeString(string, StringUtils.ESCAPE_CHAR, 
                                    charsToEscape);
  }
  
  // Unescapes all the delimiters for counters i.e {,[,(,),],}
  private static String unescape(String string) {
    return StringUtils.unEscapeString(string, StringUtils.ESCAPE_CHAR, 
                                      charsToEscape);
  }

  @Override 
  public synchronized int hashCode() {
    return counters.hashCode();
  }

  @Override
  public synchronized boolean equals(Object obj) {
    boolean isEqual = false;
    if (obj != null && obj instanceof Counters) {
      Counters other = (Counters) obj;
      if (size() == other.size()) {
        isEqual = true;
        for (Map.Entry<String, Group> entry : this.counters.entrySet()) {
          String key = entry.getKey();
          Group sourceGroup = entry.getValue();
          Group targetGroup = other.getGroup(key);
          if (!sourceGroup.equals(targetGroup)) {
            isEqual = false;
            break;
          }
        }
      }
    }
    return isEqual;
  }
  
  /**
   * Counter exception thrown when the number of counters exceed 
   * the limit
   */
  public static class CountersExceededException extends RuntimeException {
  
    private static final long serialVersionUID = 1L;

    public CountersExceededException(String msg) {
      super(msg);
    }
  }
}
