/*
 * 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.xdebugger.impl.settings;

import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.breakpoints.XBreakpointType;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.settings.DebuggerConfigurableProvider;
import com.intellij.xdebugger.settings.DebuggerSettingsCategory;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.*;

public class DebuggerConfigurable implements SearchableConfigurable.Parent {
  public static final String DISPLAY_NAME = XDebuggerBundle.message("debugger.configurable.display.name");

  static final Configurable[] EMPTY_CONFIGURABLES = new Configurable[0];
  private static final DebuggerSettingsCategory[] MERGED_CATEGORIES = {DebuggerSettingsCategory.STEPPING, DebuggerSettingsCategory.HOTSWAP};

  private Configurable myRootConfigurable;
  private Configurable[] myChildren;

  @Override
  public String getDisplayName() {
    return DISPLAY_NAME;
  }

  @Override
  public String getHelpTopic() {
    return myRootConfigurable != null ? myRootConfigurable.getHelpTopic() : null;
  }

  @Override
  public Configurable[] getConfigurables() {
    compute();

    if (myChildren.length == 0 && myRootConfigurable instanceof SearchableConfigurable.Parent) {
      return ((Parent)myRootConfigurable).getConfigurables();
    }
    else {
      return myChildren;
    }
  }

  private void compute() {
    if (myChildren != null) {
      return;
    }

    List<Configurable> configurables = new SmartList<Configurable>();
    configurables.add(new DataViewsConfigurable());

    DebuggerConfigurableProvider[] providers = DebuggerConfigurableProvider.EXTENSION_POINT.getExtensions();
    computeMergedConfigurables(providers, configurables);

    //noinspection deprecation
    for (DebuggerSettingsPanelProvider provider : getSortedProviders()) {
      configurables.addAll(provider.getConfigurables());
      @SuppressWarnings("deprecation")
      Configurable providerRootConfigurable = provider.getRootConfigurable();
      if (providerRootConfigurable != null) {
        configurables.add(providerRootConfigurable);
      }
    }

    for (DebuggerConfigurableProvider provider : providers) {
      configurables.addAll(provider.getConfigurables(DebuggerSettingsCategory.ROOT));
    }

    MergedCompositeConfigurable mergedGeneralConfigurable = computeGeneralConfigurables(providers);
    if (configurables.isEmpty() && mergedGeneralConfigurable == null) {
      myRootConfigurable = null;
      myChildren = EMPTY_CONFIGURABLES;
    }
    else if (configurables.size() == 1) {
      Configurable firstConfigurable = configurables.get(0);
      if (mergedGeneralConfigurable == null) {
        myRootConfigurable = firstConfigurable;
        myChildren = EMPTY_CONFIGURABLES;
      }
      else {
        Configurable[] generalConfigurables = mergedGeneralConfigurable.children;
        Configurable[] mergedArray = new Configurable[generalConfigurables.length + 1];
        System.arraycopy(generalConfigurables, 0, mergedArray, 0, generalConfigurables.length);
        mergedArray[generalConfigurables.length] = firstConfigurable;
        myRootConfigurable = new MergedCompositeConfigurable("", "", mergedArray);
        myChildren = firstConfigurable instanceof SearchableConfigurable.Parent ? ((Parent)firstConfigurable).getConfigurables() : EMPTY_CONFIGURABLES;
      }
    }
    else {
      myChildren = configurables.toArray(new Configurable[configurables.size()]);
      myRootConfigurable = mergedGeneralConfigurable;
    }
  }

  private static void computeMergedConfigurables(@NotNull DebuggerConfigurableProvider[] providers, @NotNull List<Configurable> result) {
    for (DebuggerSettingsCategory category : MERGED_CATEGORIES) {
      List<Configurable> configurables = getConfigurables(category, providers);
      if (!configurables.isEmpty()) {
        String id = category.name().toLowerCase(Locale.ENGLISH);
        result.add(new MergedCompositeConfigurable("debugger." + id, XDebuggerBundle.message("debugger." + id + ".display.name"),
                                                   configurables.toArray(new Configurable[configurables.size()])));
      }
    }
  }

  @Nullable
  private static MergedCompositeConfigurable computeGeneralConfigurables(@NotNull DebuggerConfigurableProvider[] providers) {
    List<Configurable> rootConfigurables = getConfigurables(DebuggerSettingsCategory.GENERAL, providers);
    if (rootConfigurables.isEmpty()) {
      return null;
    }

    Configurable[] mergedRootConfigurables = rootConfigurables.toArray(new Configurable[rootConfigurables.size()]);
    // move unnamed to top
    Arrays.sort(mergedRootConfigurables, new Comparator<Configurable>() {
      @Override
      public int compare(@NotNull Configurable o1, @NotNull Configurable o2) {
        boolean c1e = StringUtil.isEmpty(o1.getDisplayName());
        return c1e == StringUtil.isEmpty(o2.getDisplayName()) ? 0 : (c1e ? -1 : 1);
      }
    });
    return new MergedCompositeConfigurable("", "", mergedRootConfigurables);
  }

  @Override
  public void apply() throws ConfigurationException {
    if (myRootConfigurable != null) {
      myRootConfigurable.apply();
    }
  }

  @Override
  public boolean hasOwnContent() {
    compute();
    return myRootConfigurable != null;
  }

  @Override
  public boolean isVisible() {
    return XBreakpointType.EXTENSION_POINT_NAME.getExtensions().length != 0;
  }

  @Override
  public Runnable enableSearch(final String option) {
    return null;
  }

  @Override
  public JComponent createComponent() {
    compute();
    return myRootConfigurable != null ? myRootConfigurable.createComponent() : null;
  }

  @Override
  public boolean isModified() {
    return myRootConfigurable != null && myRootConfigurable.isModified();
  }

  @Override
  public void reset() {
    if (myRootConfigurable != null) {
      myRootConfigurable.reset();
    }
  }

  @Override
  public void disposeUIResources() {
    if (myRootConfigurable != null) {
      myRootConfigurable.disposeUIResources();
    }
  }

  @Override
  @NotNull
  @NonNls
  public String getId() {
    return "project.propDebugger";
  }

  @SuppressWarnings("deprecation")
  @NotNull
  private static List<DebuggerSettingsPanelProvider> getSortedProviders() {
    List<DebuggerSettingsPanelProvider> providers = null;
    for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
      DebuggerSettingsPanelProvider provider = support.getSettingsPanelProvider();
      if (providers == null) {
        providers = new SmartList<DebuggerSettingsPanelProvider>();
      }
      providers.add(provider);
    }

    if (ContainerUtil.isEmpty(providers)) {
      return Collections.emptyList();
    }

    if (providers.size() > 1) {
      Collections.sort(providers, new Comparator<DebuggerSettingsPanelProvider>() {
        @Override
        public int compare(@NotNull DebuggerSettingsPanelProvider o1, @NotNull DebuggerSettingsPanelProvider o2) {
          return o2.getPriority() - o1.getPriority();
        }
      });
    }
    return providers;
  }

  @NotNull
  static List<Configurable> getConfigurables(@NotNull DebuggerSettingsCategory category) {
    return getConfigurables(category, DebuggerConfigurableProvider.EXTENSION_POINT.getExtensions());
  }

  @NotNull
  private static List<Configurable> getConfigurables(@NotNull DebuggerSettingsCategory category, @NotNull DebuggerConfigurableProvider[] providers) {
    List<Configurable> configurables = null;
    for (DebuggerConfigurableProvider provider : providers) {
      Collection<? extends Configurable> providerConfigurables = provider.getConfigurables(category);
      if (!providerConfigurables.isEmpty()) {
        if (configurables == null) {
          configurables = new SmartList<Configurable>();
        }
        configurables.addAll(providerConfigurables);
      }
    }
    return ContainerUtil.notNullize(configurables);
  }
}
