package org.jetbrains.idea.maven.plugins.api;

import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.ProcessingContext;
import com.intellij.util.SmartList;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.model.*;
import org.jetbrains.idea.maven.utils.MavenUtil;

import java.util.*;

/**
 * @author Sergey Evdokimov
 */
public class MavenPluginParamInfo {

  private static final Logger LOG = Logger.getInstance(MavenPluginParamInfo.class);

  /**
   * This map contains descriptions of all plugins.
   */
  private static volatile Map<String, Map> myMap;

  public static Map<String, Map> getMap() {
    Map<String, Map> res = myMap;

    if (res == null) {
      res = new HashMap<String, Map>();

      for (MavenPluginDescriptor pluginDescriptor : MavenPluginDescriptor.EP_NAME.getExtensions()) {
        if (pluginDescriptor.params == null) continue;

        Pair<String, String> pluginId = MavenPluginDescriptor.parsePluginId(pluginDescriptor.mavenId);

        for (MavenPluginDescriptor.Param param : pluginDescriptor.params) {
          String[] paramPath = param.name.split("/");

          Map pluginsMap = res;

          for (int i = paramPath.length - 1; i >= 0; i--) {
            pluginsMap = MavenUtil.getOrCreate(pluginsMap, paramPath[i]);
          }

          ParamInfo paramInfo = new ParamInfo(pluginDescriptor.getPluginDescriptor().getPluginClassLoader(), param);

          Map<String, ParamInfo> goalsMap = MavenUtil.getOrCreate(pluginsMap, pluginId);

          String goal = pluginDescriptor.goal;
          assert goal == null || !goal.isEmpty();

          ParamInfo oldValue = goalsMap.put(goal, paramInfo);
          if (oldValue != null) {
            LOG.error("Duplicated maven plugin parameter descriptor: "
                      + pluginId.first + ':' + pluginId.second + " -> "
                      + (goal != null ? "[" + goal + ']' : "") + param.name);
          }
        }
      }

      myMap = res;
    }

    return res;
  }

  public static boolean isSimpleText(@NotNull XmlText paramValue) {
    PsiElement prevSibling = paramValue.getPrevSibling();
    if (!(prevSibling instanceof LeafPsiElement) || ((LeafPsiElement)prevSibling).getElementType() != XmlTokenType.XML_TAG_END) {
      return false;
    }

    PsiElement nextSibling = paramValue.getNextSibling();
    if (!(nextSibling instanceof LeafPsiElement) || ((LeafPsiElement)nextSibling).getElementType() != XmlTokenType.XML_END_TAG_START) {
      return false;
    }

    return true;
  }

  public static ParamInfoList getParamInfoList(@NotNull XmlText paramValue) {
    XmlTag tag = paramValue.getParentTag();
    if (tag == null) return ParamInfoList.EMPTY;

    return getParamInfoList(tag);
  }

  public static ParamInfoList getParamInfoList(@NotNull XmlTag paramTag) {
    XmlTag configurationTag = paramTag;
    DomElement domElement;

    Map m = getMap().get(paramTag.getName());

    while (true) {
      if (m == null) return ParamInfoList.EMPTY;

      configurationTag = configurationTag.getParentTag();
      if (configurationTag == null) return ParamInfoList.EMPTY;

      String tagName = configurationTag.getName();
      if ("configuration".equals(tagName)) {
        domElement = DomManager.getDomManager(configurationTag.getProject()).getDomElement(configurationTag);
        if (domElement instanceof MavenDomConfiguration) {
          break;
        }

        if (domElement != null) return ParamInfoList.EMPTY;
      }

      m = (Map)m.get(tagName);
    }

    Map<Pair<String, String>, Map<String, ParamInfo>> pluginsMap = m;

    MavenDomConfiguration domCfg = (MavenDomConfiguration)domElement;

    MavenDomPlugin domPlugin = domCfg.getParentOfType(MavenDomPlugin.class, true);
    if (domPlugin == null) return ParamInfoList.EMPTY;

    String pluginGroupId = domPlugin.getGroupId().getStringValue();
    String pluginArtifactId = domPlugin.getArtifactId().getStringValue();

    Map<String, ParamInfo> goalsMap;

    if (pluginGroupId == null) {
      goalsMap = pluginsMap.get(Pair.create("org.apache.maven.plugins", pluginArtifactId));
      if (goalsMap == null) {
        goalsMap = pluginsMap.get(Pair.create("org.codehaus.mojo", pluginArtifactId));
      }
    }
    else {
      goalsMap = pluginsMap.get(Pair.create(pluginGroupId, pluginArtifactId));
    }

    if (goalsMap == null) return ParamInfoList.EMPTY;

    DomElement parent = domCfg.getParent();
    if (parent instanceof MavenDomPluginExecution) {
      SmartList<ParamInfo> infos = null;

      MavenDomGoals goals = ((MavenDomPluginExecution)parent).getGoals();
      for (MavenDomGoal goal : goals.getGoals()) {
        ParamInfo info = goalsMap.get(goal.getStringValue());
        if (info != null) {
          if (infos == null) {
            infos = new SmartList<ParamInfo>();
          }

          infos.add(info);
        }
      }

      if (infos != null) {
        ParamInfo defaultInfo = goalsMap.get(null);
        if (defaultInfo != null) {
          infos.add(defaultInfo);
        }

        return new ParamInfoList(domCfg, infos);
      }
    }

    ParamInfo defaultInfo = goalsMap.get(null);
    if (defaultInfo != null) {
      return new ParamInfoList(domCfg, Collections.singletonList(defaultInfo));
    }

    return ParamInfoList.EMPTY;
  }

  public static class ParamInfoList implements Iterable<ParamInfo> {

    private static final ParamInfoList EMPTY = new ParamInfoList(null, Collections.<ParamInfo>emptyList());

    private final MavenDomConfiguration domCfg;

    private final List<ParamInfo> paramInfos;

    ParamInfoList(MavenDomConfiguration domCfg, @NotNull List<ParamInfo> paramInfos) {
      this.domCfg = domCfg;
      this.paramInfos = paramInfos;
    }

    public MavenDomConfiguration getDomCfg() {
      return domCfg;
    }

    @Override
    public Iterator<ParamInfo> iterator() {
      return paramInfos.iterator();
    }
  }

  public static class ParamInfo {
    private final ClassLoader myClassLoader;

    private final MavenPluginDescriptor.Param myParam;

    private volatile boolean myLanguageInitialized;
    private Language myLanguageInstance;
    private MavenParamLanguageProvider myLanguageProvider;

    private volatile boolean myProviderInitialized;
    private volatile MavenParamReferenceProvider myProviderInstance;

    private ParamInfo(ClassLoader classLoader, MavenPluginDescriptor.Param param) {
      myClassLoader = classLoader;
      myParam = param;
    }

    private void ensureLanguageInit() {
      if (!myLanguageInitialized) {
        if (myParam.language != null) {
          assert myParam.languageProvider == null;

          myLanguageInstance = Language.findLanguageByID(myParam.language);
        }
        else if (myParam.languageProvider != null) {
          try {
            myLanguageProvider = (MavenParamLanguageProvider)myClassLoader.loadClass(myParam.languageProvider).newInstance();
          }
          catch (Exception e) {
            throw new RuntimeException("Failed to create language provider instance", e);
          }
        }

        myLanguageInitialized = true;
      }
    }

    @Nullable
    public Language getLanguage() {
      ensureLanguageInit();
      return myLanguageInstance;
    }

    @Nullable
    public MavenParamLanguageProvider getLanguageProvider() {
      ensureLanguageInit();
      return myLanguageProvider;
    }

    public MavenPluginDescriptor.Param getParam() {
      return myParam;
    }

    public String getLanguageInjectionPrefix() {
      return myParam.languageInjectionPrefix;
    }

    public String getLanguageInjectionSuffix() {
      return myParam.languageInjectionSuffix;
    }

    public MavenParamReferenceProvider getProviderInstance() {
      if (!myProviderInitialized) {
        MavenParamReferenceProvider res = null;

        if (myParam.refProvider != null) {
          assert myParam.values == null : myParam.name;

          Object instance;

          try {
            instance = myClassLoader.loadClass(myParam.refProvider).newInstance();
          }
          catch (Exception e) {
            throw new RuntimeException("Failed to create reference provider instance", e);
          }

          if (instance instanceof MavenParamReferenceProvider) {
            res = (MavenParamReferenceProvider)instance;
          }
          else {
            res = new PsiReferenceProviderWrapper((PsiReferenceProvider)instance);
          }
        }
        else if (myParam.values != null) {
          StringTokenizer st = new StringTokenizer(myParam.values, " ,;");
          int n = st.countTokens();

          if (n == 0) throw new RuntimeException("Incorrect value of 'values' attribute for param " + myParam.name);

          String[] values = new String[n];

          for (int i = 0; i < n; i++) {
            values[i] = st.nextToken();
          }

          res = new MavenFixedValueReferenceProvider(values);
        }

        if (res != null && myParam.soft != null) {
          ((MavenSoftAwareReferenceProvider)res).setSoft(myParam.soft);
        }

        myProviderInstance = res;
        myProviderInitialized = true;
      }

      return myProviderInstance;
    }
  }

  private static class PsiReferenceProviderWrapper implements MavenParamReferenceProvider, MavenSoftAwareReferenceProvider {

    private final PsiReferenceProvider myProvider;

    private PsiReferenceProviderWrapper(PsiReferenceProvider provider) {
      this.myProvider = provider;
    }

    @Override
    public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
                                                 @NotNull MavenDomConfiguration domCfg,
                                                 @NotNull ProcessingContext context) {
      return myProvider.getReferencesByElement(element, context);
    }

    @Override
    public void setSoft(boolean soft) {
      ((MavenSoftAwareReferenceProvider)myProvider).setSoft(soft);
    }
  }

}
