/*
 * ContextFactory.java
 *
 * 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.metrics;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.metrics.spi.NullContext;

/**
 * Factory class for creating MetricsContext objects.  To obtain an instance
 * of this class, use the static <code>getFactory()</code> method.
 */
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class ContextFactory {
    
  private static final String PROPERTIES_FILE = 
    "/hadoop-metrics.properties";
  private static final String CONTEXT_CLASS_SUFFIX =
    ".class";
  private static final String DEFAULT_CONTEXT_CLASSNAME =
    "org.apache.hadoop.metrics.spi.NullContext";
    
  private static ContextFactory theFactory = null;
    
  private Map<String,Object> attributeMap = new HashMap<String,Object>();
  private Map<String,MetricsContext> contextMap = 
    new HashMap<String,MetricsContext>();
    
  // Used only when contexts, or the ContextFactory itself, cannot be
  // created.
  private static Map<String,MetricsContext> nullContextMap = 
    new HashMap<String,MetricsContext>();
    
  /** Creates a new instance of ContextFactory */
  protected ContextFactory() {
  }
    
  /**
   * Returns the value of the named attribute, or null if there is no 
   * attribute of that name.
   *
   * @param attributeName the attribute name
   * @return the attribute value
   */
  public Object getAttribute(String attributeName) {
    return attributeMap.get(attributeName);
  }
    
  /**
   * Returns the names of all the factory's attributes.
   * 
   * @return the attribute names
   */
  public String[] getAttributeNames() {
    String[] result = new String[attributeMap.size()];
    int i = 0;
    // for (String attributeName : attributeMap.keySet()) {
    Iterator it = attributeMap.keySet().iterator();
    while (it.hasNext()) {
      result[i++] = (String) it.next();
    }
    return result;
  }
    
  /**
   * Sets the named factory attribute to the specified value, creating it
   * if it did not already exist.  If the value is null, this is the same as
   * calling removeAttribute.
   *
   * @param attributeName the attribute name
   * @param value the new attribute value
   */
  public void setAttribute(String attributeName, Object value) {
    attributeMap.put(attributeName, value);
  }

  /**
   * Removes the named attribute if it exists.
   *
   * @param attributeName the attribute name
   */
  public void removeAttribute(String attributeName) {
    attributeMap.remove(attributeName);
  }
    
  /**
   * Returns the named MetricsContext instance, constructing it if necessary 
   * using the factory's current configuration attributes. <p/>
   * 
   * When constructing the instance, if the factory property 
   * <i>contextName</i>.class</code> exists, 
   * its value is taken to be the name of the class to instantiate.  Otherwise,
   * the default is to create an instance of 
   * <code>org.apache.hadoop.metrics.spi.NullContext</code>, which is a 
   * dummy "no-op" context which will cause all metric data to be discarded.
   * 
   * @param contextName the name of the context
   * @return the named MetricsContext
   */
  public synchronized MetricsContext getContext(String refName, String contextName)
      throws IOException, ClassNotFoundException,
             InstantiationException, IllegalAccessException {
    MetricsContext metricsContext = contextMap.get(refName);
    if (metricsContext == null) {
      String classNameAttribute = refName + CONTEXT_CLASS_SUFFIX;
      String className = (String) getAttribute(classNameAttribute);
      if (className == null) {
        className = DEFAULT_CONTEXT_CLASSNAME;
      }
      Class contextClass = Class.forName(className);
      metricsContext = (MetricsContext) contextClass.newInstance();
      metricsContext.init(contextName, this);
      contextMap.put(contextName, metricsContext);
    }
    return metricsContext;
  }

  public synchronized MetricsContext getContext(String contextName)
    throws IOException, ClassNotFoundException, InstantiationException,
           IllegalAccessException {
    return getContext(contextName, contextName);
  }
  
  /** 
   * Returns all MetricsContexts built by this factory.
   */
  public synchronized Collection<MetricsContext> getAllContexts() {
    // Make a copy to avoid race conditions with creating new contexts.
    return new ArrayList<MetricsContext>(contextMap.values());
  }
    
  /**
   * Returns a "null" context - one which does nothing.
   */
  public static synchronized MetricsContext getNullContext(String contextName) {
    MetricsContext nullContext = nullContextMap.get(contextName);
    if (nullContext == null) {
      nullContext = new NullContext();
      nullContextMap.put(contextName, nullContext);
    }
    return nullContext;
  }
    
  /**
   * Returns the singleton ContextFactory instance, constructing it if 
   * necessary. <p/>
   * 
   * When the instance is constructed, this method checks if the file 
   * <code>hadoop-metrics.properties</code> exists on the class path.  If it 
   * exists, it must be in the format defined by java.util.Properties, and all 
   * the properties in the file are set as attributes on the newly created
   * ContextFactory instance.
   *
   * @return the singleton ContextFactory instance
   */
  public static synchronized ContextFactory getFactory() throws IOException {
    if (theFactory == null) {
      theFactory = new ContextFactory();
      theFactory.setAttributes();
    }
    return theFactory;
  }
    
  private void setAttributes() throws IOException {
    InputStream is = getClass().getResourceAsStream(PROPERTIES_FILE);
    if (is != null) {
      try {
        Properties properties = new Properties();
        properties.load(is);
        //for (Object propertyNameObj : properties.keySet()) {
        Iterator it = properties.keySet().iterator();
        while (it.hasNext()) {
          String propertyName = (String) it.next();
          String propertyValue = properties.getProperty(propertyName);
          setAttribute(propertyName, propertyValue);
        }
      } finally {
        is.close();
      }
    }
  }
    
}
