/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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.intellij.util.lang;

import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.Stack;
import com.intellij.util.io.URLUtil;
import org.jetbrains.annotations.Nullable;
import sun.misc.Resource;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;

public class ClassPath {
  private static final ResourceStringLoaderIterator ourCheckedIterator = new ResourceStringLoaderIterator(true);
  private static final ResourceStringLoaderIterator ourUncheckedIterator = new ResourceStringLoaderIterator(false);
  private static final LoaderCollector ourLoaderCollector = new LoaderCollector();

  private final Stack<URL> myUrls = new Stack<URL>();
  private final List<Loader> myLoaders = new ArrayList<Loader>();
  private final Map<URL, Loader> myLoadersMap = new HashMap<URL, Loader>();
  private final ClasspathCache myCache = new ClasspathCache();

  private final boolean myCanLockJars;
  private final boolean myCanUseCache;
  private final boolean myAcceptUnescapedUrls;
  private final boolean myPreloadJarContents;

  public ClassPath(List<URL> urls, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, boolean preloadJarContents) {
    myCanLockJars = canLockJars;
    myCanUseCache = canUseCache;
    myAcceptUnescapedUrls = acceptUnescapedUrls;
    myPreloadJarContents = preloadJarContents;
    push(urls);
  }

  // Accessed by reflection from PluginClassLoader // TODO: do we need it?
  void addURL(URL url) {
    push(Collections.singletonList(url));
  }

  private void push(List<URL> urls) {
    if (!urls.isEmpty()) {
      synchronized (myUrls) {
        for (int i = urls.size() - 1; i >= 0; i--) {
          myUrls.push(urls.get(i));
        }
      }
    }
  }

  @Nullable
  public Resource getResource(String s, boolean flag) {
    final long started = startTiming();
    try {
      int i;
      if (myCanUseCache) {
        Resource prevResource = myCache.iterateLoaders(s, flag ? ourCheckedIterator : ourUncheckedIterator, s, this);
        if (prevResource != null) return prevResource;

        synchronized (myUrls) {
          if (myUrls.isEmpty()) return null;
        }

        i = myLoaders.size();
      }
      else {
        i = 0;
      }

      String shortName = ClasspathCache.transformName(s);

      Loader loader;
      while ((loader = getLoader(i++)) != null) {
        if (myCanUseCache) {
          if (!myCache.loaderHasName(s, shortName, loader)) continue;
        }
        Resource resource = loader.getResource(s, flag);
        if (resource != null) {
          return resource;
        }
      }
    }
    finally {
      logTiming(this, started, s);
    }

    return null;
  }

  public Enumeration<URL> getResources(final String name, final boolean check) {
    return new MyEnumeration(name, check);
  }

  @Nullable
  private synchronized Loader getLoader(int i) {
    while (myLoaders.size() < i + 1) {
      boolean lastOne;
      URL url;
      synchronized (myUrls) {
        if (myUrls.empty()) {
          if (myCanUseCache) myCache.nameSymbolsLoaded();
          return null;
        }
        url = myUrls.pop();
        lastOne = myUrls.isEmpty();
      }

      if (myLoadersMap.containsKey(url)) continue;

      Loader loader;
      try {
        loader = getLoader(url, myLoaders.size());
        if (loader == null) continue;
      }
      catch (IOException ioexception) {
        continue;
      }

      myLoaders.add(loader);
      myLoadersMap.put(url, loader);
      if (lastOne && myCanUseCache) {
        myCache.nameSymbolsLoaded();
      }
    }

    return myLoaders.get(i);
  }

  @Nullable
  private Loader getLoader(final URL url, int index) throws IOException {
    String path;

    if (myAcceptUnescapedUrls) {
      path = url.getFile();
    }
    else {
      try {
        path = url.toURI().getSchemeSpecificPart();
      }
      catch (URISyntaxException thisShouldNotHappen) {
        //noinspection CallToPrintStackTrace
        thisShouldNotHappen.printStackTrace();
        path = url.getFile();
      }
    }

    Loader loader = null;
    if (path != null && URLUtil.FILE_PROTOCOL.equals(url.getProtocol())) {
      File file = new File(path);
      if (file.isDirectory()) {
        loader = new FileLoader(url, index);
      }
      else if (file.isFile()) {
        loader = new JarLoader(url, myCanLockJars, index);
        if (myPreloadJarContents) {
          ((JarLoader)loader).preloadClasses();
        }
      }
    }

    if (loader != null && myCanUseCache) {
      try {
        loader.buildCache(myCache);
      }
      catch (Throwable e) {
        // TODO: log can't create loader
      }
    }

    return loader;
  }

  private class MyEnumeration implements Enumeration<URL> {
    private int myIndex = 0;
    private Resource myRes = null;
    private final String myName;
    private final String myShortName;
    private final boolean myCheck;
    private final List<Loader> myLoaders;

    public MyEnumeration(String name, boolean check) {
      myName = name;
      myShortName = ClasspathCache.transformName(name);
      myCheck = check;
      List<Loader> loaders = null;

      if (myCanUseCache) {
        synchronized (myUrls) {
          if (myUrls.isEmpty()) {
            loaders = new SmartList<Loader>();
            myCache.iterateLoaders(name, ourLoaderCollector, loaders, this);
            if (!name.endsWith("/")) {
              myCache.iterateLoaders(name.concat("/"), ourLoaderCollector, loaders, this);
            }
          }
        }
      }

      myLoaders = loaders;
    }

    private boolean next() {
      if (myRes != null) return true;

      long started = startTiming();
      try {
        Loader loader;
        if (myLoaders != null) {
          while (myIndex < myLoaders.size()) {
            loader = myLoaders.get(myIndex++);
            if (!myCache.loaderHasName(myName, myShortName, loader)) {
              myRes = null;
              continue;
            }
            myRes = loader.getResource(myName, myCheck);
            if (myRes != null) return true;
          }
        }
        else {
          while ((loader = getLoader(myIndex++)) != null) {
            if (!myCache.loaderHasName(myName, myShortName, loader)) continue;
            myRes = loader.getResource(myName, myCheck);
            if (myRes != null) return true;
          }
        }
      }
      finally {
        logTiming(ClassPath.this, started, myName);
      }

      return false;
    }

    public boolean hasMoreElements() {
      return next();
    }

    public URL nextElement() {
      if (!next()) {
        throw new NoSuchElementException();
      }
      else {
        Resource resource = myRes;
        myRes = null;
        return resource.getURL();
      }
    }
  }

  private static class ResourceStringLoaderIterator extends ClasspathCache.LoaderIterator<Resource, String, ClassPath> {
    private final boolean myFlag;

    private ResourceStringLoaderIterator(boolean flag) {
      myFlag = flag;
    }

    @Override
    Resource process(Loader loader, String s, ClassPath classPath) {
      if (!classPath.myCache.loaderHasName(s, ClasspathCache.transformName(s), loader)) return null;
      final Resource resource = loader.getResource(s, myFlag);
      if (resource != null) {
        printOrder(loader, s, resource);
        return resource;
      }
      return null;
    }
  }

  private static class LoaderCollector extends ClasspathCache.LoaderIterator<Object, List<Loader>, Object> {
    @Override
    Object process(Loader loader, List<Loader> parameter, Object parameter2) {
      parameter.add(loader);
      return null;
    }
  }

  private static final boolean ourDumpOrder = "true".equals(System.getProperty("idea.dump.order"));
  private static PrintStream ourOrder;
  private static long ourOrderSize;
  private static final Set<String> ourOrderedUrls = new HashSet<String>();

  @SuppressWarnings("UseOfSystemOutOrSystemErr")
  private static synchronized void printOrder(Loader loader, String url, Resource resource) {
    if (!ourDumpOrder) return;
    if (!ourOrderedUrls.add(url)) return;

    String home = FileUtil.toSystemIndependentName(PathManager.getHomePath());
    try {
      ourOrderSize += resource.getContentLength();
    }
    catch (IOException e) {
      e.printStackTrace(System.out);
    }

    if (ourOrder == null) {
      final File orderFile = new File(PathManager.getBinPath() + File.separator + "order.txt");
      try {
        if (!FileUtil.ensureCanCreateFile(orderFile)) return;
        ourOrder = new PrintStream(new FileOutputStream(orderFile, true));
        ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
          public void run() {
            ourOrder.close();
            System.out.println(ourOrderSize);
          }
        });
      }
      catch (IOException e) {
        return;
      }
    }

    if (ourOrder != null) {
      String jarURL = FileUtil.toSystemIndependentName(loader.getBaseURL().getFile());
      jarURL = StringUtil.trimStart(jarURL, "file:/");
      if (jarURL.startsWith(home)) {
        jarURL = jarURL.replaceFirst(home, "");
        jarURL = StringUtil.trimEnd(jarURL, "!/");
        ourOrder.println(url + ":" + jarURL);
      }
    }
  }


  private static final boolean ourLogTiming = Boolean.getBoolean("idea.print.classpath.timing");
  private static long ourTotalTime = 0;
  private static int ourTotalRequests = 0;

  private static long startTiming() {
    return ourLogTiming ? System.nanoTime() : 0;
  }

  @SuppressWarnings("UseOfSystemOutOrSystemErr")
  private static void logTiming(ClassPath path, long started, String msg) {
    if (!ourLogTiming) return;

    long time = System.nanoTime() - started;
    ourTotalTime += time;
    ++ourTotalRequests;
    if (time > 10000000L) {
      System.out.println((time / 1000000) + " ms for " + msg);
    }
    if (ourTotalRequests % 1000 == 0) {
      System.out.println(path.toString() + ", requests:" + ourTotalRequests + ", time:" + (ourTotalTime / 1000000) + "ms");
    }
  }
}
