/*
 * Copyright 2007 Google Inc.
 *
 * Licensed 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 com.tonicsystems.jarjar.util;

import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;

public class ClassPathIterator implements Iterator<ClassPathEntry> {
  private static final FileFilter CLASS_FILTER =
      new FileFilter() {
        public boolean accept(File file) {
          return file.isDirectory() || isClass(file.getName());
        }
      };

  private static final FileFilter JAR_FILTER =
      new FileFilter() {
        public boolean accept(File file) {
          return hasExtension(file.getName(), ".jar");
        }
      };

  private final Iterator<File> files;
  private Iterator<ClassPathEntry> entries = Collections.<ClassPathEntry>emptyList().iterator();
  private ClassPathEntry next;
  private List<ZipFile> zips = new ArrayList<ZipFile>();

  public ClassPathIterator(String classPath) throws IOException {
    this(new File(System.getProperty("user.dir")), classPath, null);
  }

  public ClassPathIterator(File parent, String classPath, String delim) throws IOException {
    if (delim == null) {
      delim = System.getProperty("path.separator");
    }
    StringTokenizer st = new StringTokenizer(classPath, delim);
    List<File> fileList = new ArrayList<File>();
    while (st.hasMoreTokens()) {
      String part = (String) st.nextElement();
      boolean wildcard = false;
      if (part.endsWith("/*")) {
        part = part.substring(0, part.length() - 1);
        if (part.indexOf('*') >= 0) {
          throw new IllegalArgumentException("Multiple wildcards are not allowed: " + part);
        }
        wildcard = true;
      } else if (part.indexOf('*') >= 0) {
        throw new IllegalArgumentException("Incorrect wildcard usage: " + part);
      }

      File file = new File(part);
      if (!file.isAbsolute()) {
        file = new File(parent, part);
      }
      if (!file.exists()) {
        throw new IllegalArgumentException("File " + file + " does not exist");
      }

      if (wildcard) {
        if (!file.isDirectory()) {
          throw new IllegalArgumentException("File " + file + " + is not a directory");
        }
        fileList.addAll(findFiles(file, JAR_FILTER, false, new ArrayList<File>()));
      } else {
        fileList.add(file);
      }
    }
    this.files = fileList.iterator();
    advance();
  }

  public boolean hasNext() {
    return next != null;
  }

  /** Closes all zip files opened by this iterator. */
  public void close() throws IOException {
    next = null;
    for (ZipFile zip : zips) {
      zip.close();
    }
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }

  public ClassPathEntry next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    ClassPathEntry result = next;
    try {
      advance();
    } catch (IOException e) {
      throw new RuntimeIOException(e);
    }
    return result;
  }

  private void advance() throws IOException {
    if (!entries.hasNext()) {
      if (!files.hasNext()) {
        next = null;
        return;
      }
      File file = files.next();
      if (hasExtension(file.getName(), ".jar")) {
        ZipFile zip = new JarFile(file);
        zips.add(zip);
        entries = new ZipIterator(zip);
      } else if (hasExtension(file.getName(), ".zip")) {
        ZipFile zip = new ZipFile(file);
        zips.add(zip);
        entries = new ZipIterator(zip);
      } else if (file.isDirectory()) {
        entries = new FileIterator(file);
      } else {
        throw new IllegalArgumentException("Do not know how to handle " + file);
      }
    }

    boolean foundClass = false;
    while (!foundClass && entries.hasNext()) {
      next = entries.next();
      foundClass = isClass(next.getName());
    }
    if (!foundClass) {
      advance();
    }
  }

  private static class ZipIterator implements Iterator<ClassPathEntry> {
    private final ZipFile zip;
    private final Enumeration<? extends ZipEntry> entries;

    ZipIterator(ZipFile zip) {
      this.zip = zip;
      this.entries = zip.entries();
    }

    public boolean hasNext() {
      return entries.hasMoreElements();
    }

    public void remove() {
      throw new UnsupportedOperationException();
    }

    public ClassPathEntry next() {
      final ZipEntry entry = entries.nextElement();
      return new ClassPathEntry() {
        public String getSource() {
          return zip.getName();
        }

        public String getName() {
          return entry.getName();
        }

        public InputStream openStream() throws IOException {
          return zip.getInputStream(entry);
        }
      };
    }
  }

  private static class FileIterator implements Iterator<ClassPathEntry> {
    private final File dir;
    private final Iterator<File> entries;

    FileIterator(File dir) {
      this.dir = dir;
      this.entries = findFiles(dir, CLASS_FILTER, true, new ArrayList<File>()).iterator();
    }

    public boolean hasNext() {
      return entries.hasNext();
    }

    public void remove() {
      throw new UnsupportedOperationException();
    }

    public ClassPathEntry next() {
      final File file = entries.next();
      return new ClassPathEntry() {
        public String getSource() throws IOException {
          return dir.getCanonicalPath();
        }

        public String getName() {
          return file.getName();
        }

        public InputStream openStream() throws IOException {
          return new BufferedInputStream(new FileInputStream(file));
        }
      };
    }
  }

  private static List<File> findFiles(
      File dir, FileFilter filter, boolean recurse, List<File> collect) {
    for (File file : dir.listFiles(filter)) {
      if (recurse && file.isDirectory()) {
        findFiles(file, filter, recurse, collect);
      } else {
        collect.add(file);
      }
    }
    return collect;
  }

  private static boolean isClass(String name) {
    return hasExtension(name, ".class");
  }

  private static boolean hasExtension(String name, String ext) {
    if (name.length() < ext.length()) {
      return false;
    }
    String actual = name.substring(name.length() - ext.length());
    return actual.equals(ext) || actual.equals(ext.toUpperCase());
  }
}
