/*
 * Copyright 2000-2009 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.openapi.extensions;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl;
import com.intellij.openapi.util.Disposer;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Extensions {
  public static final ExtensionPointName<AreaListener> AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName<AreaListener>("com.intellij.arealistener");
  private static LogProvider ourLogger = new SimpleLogProvider();
  private static Map<AreaInstance,ExtensionsAreaImpl> ourAreaInstance2area = new THashMap<AreaInstance, ExtensionsAreaImpl>();
  private static Map<String,AreaClassConfiguration> ourAreaClass2Configuration = new THashMap<String, AreaClassConfiguration>();

  @NotNull private static ExtensionsAreaImpl ourRootArea = createRootArea();

  private Extensions() {
  }

  @NotNull
  private static ExtensionsAreaImpl createRootArea() {
    ExtensionsAreaImpl rootArea = new ExtensionsAreaImpl(null, null, null, ourLogger);
    rootArea.registerExtensionPoint(AREA_LISTENER_EXTENSION_POINT.getName(), AreaListener.class.getName());
    return rootArea;
  }

  public static void setSynchronized() {
    assert ourAreaInstance2area.isEmpty();
    assert ourAreaClass2Configuration.isEmpty();

    ourAreaInstance2area = new ConcurrentHashMap<AreaInstance, ExtensionsAreaImpl>();
    ourAreaClass2Configuration = new ConcurrentHashMap<String, AreaClassConfiguration>();
  }

  @NotNull
  public static ExtensionsArea getRootArea() {
    return ourRootArea;
  }

  @NotNull
  public static ExtensionsArea getArea(@Nullable AreaInstance areaInstance) {
    if (areaInstance == null) {
      return ourRootArea;
    }
    ExtensionsAreaImpl area = ourAreaInstance2area.get(areaInstance);
    if (area == null) {
      throw new IllegalArgumentException("No area instantiated for: " + areaInstance);
    }
    return area;
  }

  @TestOnly
  public static void cleanRootArea(@NotNull Disposable parentDisposable) {
    final ExtensionsAreaImpl oldRootArea = (ExtensionsAreaImpl)getRootArea();
    final ExtensionsAreaImpl newArea = createRootArea();
    ourRootArea = newArea;
    oldRootArea.notifyAreaReplaced();
    Disposer.register(parentDisposable, new Disposable() {
      @Override
      public void dispose() {
        ourRootArea = oldRootArea;
        newArea.notifyAreaReplaced();
      }
    });
  }

  @NotNull
  public static Object[] getExtensions(@NonNls String extensionPointName) {
    return getExtensions(extensionPointName, null);
  }

  @NotNull
  @SuppressWarnings({"unchecked"})
  public static <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName) {
    return (T[])getExtensions(extensionPointName.getName(), null);
  }

  @NotNull
  @SuppressWarnings({"unchecked"})
  public static <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName, AreaInstance areaInstance) {
    // keep it until 1.7 JDK
    return Extensions.<T>getExtensions(extensionPointName.getName(), areaInstance);
  }

  @NotNull
  public static <T> T[] getExtensions(String extensionPointName, @Nullable AreaInstance areaInstance) {
    ExtensionsArea area = getArea(areaInstance);
    ExtensionPoint<T> extensionPoint = area.getExtensionPoint(extensionPointName);
    return extensionPoint.getExtensions();
  }

  @NotNull
  public static <T, U extends T> U findExtension(@NotNull ExtensionPointName<T> extensionPointName, @NotNull Class<U> extClass) {
    for (T t : getExtensions(extensionPointName)) {
      if (extClass.isInstance(t)) {
        //noinspection unchecked
        return (U) t;
      }
    }
    throw new IllegalArgumentException("could not find extension implementation " + extClass);
  }

  @NotNull
  public static <T, U extends T> U findExtension(@NotNull ExtensionPointName<T> extensionPointName, AreaInstance areaInstance, @NotNull Class<U> extClass) {
    for (T t : getExtensions(extensionPointName, areaInstance)) {
      if (extClass.isInstance(t)) {
        //noinspection unchecked
        return (U) t;
      }
    }
    throw new IllegalArgumentException("could not find extension implementation " + extClass);
  }

  public static void instantiateArea(@NonNls @NotNull String areaClass, @NotNull AreaInstance areaInstance, @Nullable AreaInstance parentAreaInstance) {
    AreaClassConfiguration configuration = ourAreaClass2Configuration.get(areaClass);
    if (configuration == null) {
      throw new IllegalArgumentException("Area class is not registered: " + areaClass);
    }
    ExtensionsArea parentArea = getArea(parentAreaInstance);
    if (!equals(parentArea.getAreaClass(), configuration.getParentClassName())) {
      throw new IllegalArgumentException("Wrong parent area. Expected class: " + configuration.getParentClassName() + " actual class: " + parentArea.getAreaClass());
    }
    ExtensionsAreaImpl area = new ExtensionsAreaImpl(areaClass, areaInstance, parentArea.getPicoContainer(), ourLogger);
    if (ourAreaInstance2area.put(areaInstance, area) != null) {
      throw new IllegalArgumentException("Area already instantiated for: " + areaInstance);
    }
    for (AreaListener listener : getAreaListeners()) {
      listener.areaCreated(areaClass, areaInstance);
    }
  }

  @NotNull
  private static AreaListener[] getAreaListeners() {
    return getRootArea().getExtensionPoint(AREA_LISTENER_EXTENSION_POINT).getExtensions();
  }

  public static void registerAreaClass(@NonNls @NotNull String areaClass, @Nullable @NonNls String parentAreaClass) {
    if (ourAreaClass2Configuration.containsKey(areaClass)) {
      // allow duplicate area class registrations if they are the same - fixing duplicate registration in tests is much more trouble
      AreaClassConfiguration configuration = ourAreaClass2Configuration.get(areaClass);
      if (!equals(configuration.getParentClassName(), parentAreaClass)) {
        throw new RuntimeException("Area class already registered: " + areaClass + ", "+ ourAreaClass2Configuration.get(areaClass));
      }
      else {
        return;
      }
    }
    AreaClassConfiguration configuration = new AreaClassConfiguration(areaClass, parentAreaClass);
    ourAreaClass2Configuration.put(areaClass, configuration);
  }

  public static void disposeArea(@NotNull AreaInstance areaInstance) {
    assert ourAreaInstance2area.containsKey(areaInstance);

    String areaClass = ourAreaInstance2area.get(areaInstance).getAreaClass();
    if (areaClass == null) {
      throw new IllegalArgumentException("Area class is null (area never instantiated?). Instance: " + areaInstance);
    }
    try {
      for (AreaListener listener : getAreaListeners()) {
        listener.areaDisposing(areaClass, areaInstance);
      }
    }
    finally {
      ourAreaInstance2area.remove(areaInstance);
    }
  }

  private static boolean equals(@Nullable Object object1, @Nullable Object object2) {
    return object1 == object2 || object1 != null && object2 != null && object1.equals(object2);
  }

  public static void setLogProvider(@NotNull LogProvider logProvider) {
    ourLogger = logProvider;
  }

  private static class AreaClassConfiguration {
    private final String myClassName;
    private final String myParentClassName;

    AreaClassConfiguration(@NotNull String className, String parentClassName) {
      myClassName = className;
      myParentClassName = parentClassName;
    }

    @NotNull
    public String getClassName() {
      return myClassName;
    }

    public String getParentClassName() {
      return myParentClassName;
    }
  }

  @SuppressWarnings("CallToPrintStackTrace")
  public static class SimpleLogProvider implements LogProvider {
    @Override
    public void error(String message) {
      new Throwable(message).printStackTrace();
    }

    @Override
    public void error(String message, @NotNull Throwable t) {
      System.err.println(message);
      t.printStackTrace();
    }

    @Override
    public void error(@NotNull Throwable t) {
      t.printStackTrace();
    }

    @Override
    public void warn(String message) {
      System.err.println(message);
    }

    @Override
    public void warn(String message, @NotNull Throwable t) {
      System.err.println(message);
      t.printStackTrace();
    }

    @Override
    public void warn(@NotNull Throwable t) {
      t.printStackTrace();
    }
  }
}
