/*
 * Copyright 2000-2013 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.jetbrains.python.documentation;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.intellij.openapi.components.*;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.intellij.psi.util.QualifiedName;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yole
 */
@State(
  name = "PythonDocumentationMap",
  storages = {
  @Storage(
    file = StoragePathMacros.APP_CONFIG + "/other.xml")
    }
)
public class PythonDocumentationMap implements PersistentStateComponent<PythonDocumentationMap.State> {
  public static PythonDocumentationMap getInstance() {
    return ServiceManager.getService(PythonDocumentationMap.class);
  }

  public static class Entry {
    private String myPrefix;
    private String myUrlPattern;

    public Entry() {
    }

    public Entry(String prefix, String urlPattern) {
      myPrefix = prefix;
      myUrlPattern = urlPattern;
    }

    public String getPrefix() {
      return myPrefix;
    }

    public String getUrlPattern() {
      return myUrlPattern;
    }

    public void setPrefix(String prefix) {
      myPrefix = prefix;
    }

    public void setUrlPattern(String urlPattern) {
      myUrlPattern = urlPattern;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      Entry entry = (Entry)o;

      if (!myPrefix.equals(entry.myPrefix)) return false;
      if (!myUrlPattern.equals(entry.myUrlPattern)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = myPrefix.hashCode();
      result = 31 * result + myUrlPattern.hashCode();
      return result;
    }
  }

  public static class State {
    private List<Entry> myEntries = new ArrayList<Entry>();

    public State() {
      addEntry("PyQt4", "http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/{class.name.lower}.html#{function.name}");
      addEntry("PySide", "http://srinikom.github.com/pyside-docs/{module.name.slashes}/{class.name}.html#{module.name}.{element.qname}");
      addEntry("gtk", "http://library.gnome.org/devel/pygtk/stable/class-gtk{class.name.lower}.html#method-gtk{class.name.lower}--{function.name.dashes}");
      addEntry("wx", "http://www.wxpython.org/docs/api/{module.name}.{class.name}-class.html#{function.name}");
      addEntry("numpy", "http://docs.scipy.org/doc/numpy/reference/{}generated/{module.name}.{element.name}.html");
      addEntry("scipy", "http://docs.scipy.org/doc/scipy/reference/{}generated/{module.name}.{element.name}.html");
      addEntry("kivy", "http://kivy.org/docs/api-{module.name}.html");
    }

    public List<Entry> getEntries() {
      return myEntries;
    }

    public void setEntries(List<Entry> entries) {
      myEntries = entries;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      State state = (State)o;
      return Sets.newHashSet(myEntries).equals(Sets.newHashSet(state.getEntries()));
    }

    @Override
    public int hashCode() {
      return myEntries != null ? myEntries.hashCode() : 0;
    }

    private void addEntry(String qName, String pattern) {
      myEntries.add(new Entry(qName, pattern));
    }
  }

  private State myState = new State();

  @Override
  public State getState() {
    return myState;
  }

  @Override
  public void loadState(State state) {
    myState = state;
  }

  public List<Entry> getEntries() {
    return ImmutableList.copyOf(myState.getEntries());
  }

  public void setEntries(List<Entry> entries) {
    myState.setEntries(entries);
  }

  @Nullable
  public String urlFor(QualifiedName moduleQName, @Nullable PsiNamedElement element, String pyVersion) {
    for (Entry entry : myState.myEntries) {
      if (moduleQName.matchesPrefix(QualifiedName.fromDottedString(entry.myPrefix))) {
        return transformPattern(entry.myUrlPattern, moduleQName, element, pyVersion);
      }
    }
    return null;
  }

  @Nullable
  public String rootUrlFor(QualifiedName moduleQName) {
    for (Entry entry : myState.myEntries) {
      if (moduleQName.matchesPrefix(QualifiedName.fromDottedString(entry.myPrefix))) {
        return rootForPattern(entry.myUrlPattern);
      }
    }
    return null;
  }

  private static String rootForPattern(String urlPattern) {
    int pos = urlPattern.indexOf('{');
    return pos >= 0 ? urlPattern.substring(0, pos) : urlPattern;
  }

  @Nullable
  private static String transformPattern(@NotNull String urlPattern, QualifiedName moduleQName, @Nullable PsiNamedElement element,
                                         String pyVersion) {
    Map<String, String> macros = new HashMap<String, String>();
    macros.put("element.name", element == null ? null : element.getName());
    PyClass pyClass = element == null ? null : PsiTreeUtil.getParentOfType(element, PyClass.class, false);
    macros.put("class.name", pyClass == null ? null : pyClass.getName());
    if (element != null) {
      StringBuilder qName = new StringBuilder(moduleQName.toString()).append(".");
      if (element instanceof PyFunction && ((PyFunction)element).getContainingClass() != null) {
        qName.append(((PyFunction)element).getContainingClass().getName()).append(".");
      }
      qName.append(element.getName());
      macros.put("element.qname", qName.toString());
    }
    else {
      macros.put("element.qname", "");
    }
    macros.put("function.name", element instanceof PyFunction ? element.getName() : "");
    macros.put("module.name", moduleQName.toString());
    macros.put("python.version", pyVersion);
    final String pattern = transformPattern(urlPattern, macros);
    if (pattern == null) {
      return rootForPattern(urlPattern);
    }
    return pattern;
  }

  @Nullable
  private static String transformPattern(@NotNull String urlPattern, Map<String, String> macroValues) {
    for (Map.Entry<String, String> entry : macroValues.entrySet()) {
      if (entry.getValue() == null) {
        if (urlPattern.contains("{" + entry.getKey())) {
          return null;
        }
        continue;
      }
      urlPattern = urlPattern
        .replace("{" + entry.getKey() + "}", entry.getValue())
        .replace("{" + entry.getKey() + ".lower}", entry.getValue().toLowerCase())
        .replace("{" + entry.getKey() + ".slashes}", entry.getValue().replace(".", "/"))
        .replace("{" + entry.getKey() + ".dashes}", entry.getValue().replace("_", "-"));

    }
    return urlPattern.replace("{}", "");
  }
}
