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

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.log4j.Logger;

public class ClassUtils {
  static Logger log = Logger.getLogger(ClassUtils.class);
  
  /**
   * Attempts to list all the classes in the specified package as determined
   * by the context class loader
   * 
   * @param pckgname
   *            the package name to search
   * @return a list of classes that exist within that package
   * @throws ClassNotFoundException
   *             if something went wrong
   */
  public static List<Class> getClassesForPackage(String pckgname)
      throws ClassNotFoundException {
    // This will hold a list of directories matching the pckgname.
    // There may be more than one if a package is split over multiple jars/paths
    List<Class> classes = new ArrayList<Class>();
    ArrayList<File> directories = new ArrayList<File>();
    try {
      ClassLoader cld = Thread.currentThread().getContextClassLoader();
      if (cld == null) {
        throw new ClassNotFoundException("Can't get class loader.");
      }
      // Ask for all resources for the path
      Enumeration<URL> resources = cld.getResources(pckgname.replace('.', '/'));
      while (resources.hasMoreElements()) {
        URL res = resources.nextElement();
        if (res.getProtocol().equalsIgnoreCase("jar")) {
          JarURLConnection conn = (JarURLConnection) res.openConnection();
          JarFile jar = conn.getJarFile();
          for (JarEntry e : Collections.list(jar.entries())) {

            if (e.getName().startsWith(pckgname.replace('.', '/'))
                && e.getName().endsWith(".class") && !e.getName().contains("$")) {
              String className = e.getName().replace("/", ".").substring(0,
                  e.getName().length() - 6);
              classes.add(Class.forName(className));
            }
          }
        } else
          directories.add(new File(URLDecoder.decode(res.getPath(), "UTF-8")));
      }
    } catch (NullPointerException x) {
      throw new ClassNotFoundException(pckgname + " does not appear to be "
          + "a valid package (Null pointer exception)");
    } catch (UnsupportedEncodingException encex) {
      throw new ClassNotFoundException(pckgname + " does not appear to be "
          + "a valid package (Unsupported encoding)");
    } catch (IOException ioex) {
      throw new ClassNotFoundException("IOException was thrown when trying "
          + "to get all resources for " + pckgname);
    }

    // For every directory identified capture all the .class files
    for (File directory : directories) {
      if (directory.exists()) {
        // Get the list of the files contained in the package
        String[] files = directory.list();
        if (files != null ) {
          for (String file : files) {
            // we are only interested in .class files
            if (file.endsWith(".class")) {
              // removes the .class extension
              classes.add(Class.forName(pckgname + '.'
                + file.substring(0, file.length() - 6)));
            }
          }
        }
      } else {
        throw new ClassNotFoundException(pckgname + " (" + directory.getPath()
            + ") does not appear to be a valid package");
      }
    }
    return classes;
  }

  public static List<Class> getClassessOfInterface(String thePackage,
      Class theInterface) {
    List<Class> classList = new ArrayList<Class>();
    try {
      for (Class discovered : getClassesForPackage(thePackage)) {
        if (Arrays.asList(discovered.getInterfaces()).contains(theInterface)) {
          classList.add(discovered);
        }
      }
    } catch (ClassNotFoundException ex) {
      log.error(ExceptionUtil.getStackTrace(ex));
    }

    return classList;
  }
  

}
