package org.intellij.lang.xpath.xslt.impl.references;

import com.intellij.javaee.ExternalResourceManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ProcessingContext;
import com.intellij.util.SmartList;
import com.intellij.util.io.URLUtil;
import org.intellij.lang.xpath.psi.impl.ResolveUtil;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.impl.XsltIncludeIndex;
import org.intellij.lang.xpath.xslt.psi.*;
import org.intellij.lang.xpath.xslt.util.*;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class XsltReferenceProvider extends PsiReferenceProvider {
  private static final Key<CachedValue<PsiReference[]>> CACHED_XSLT_REFS = Key.create("CACHED_XSLT_REFS");

  private final XsltElementFactory myXsltElementFactory = XsltElementFactory.getInstance();

  private static final Pattern ELEMENT_PATTERN = Pattern.compile("(?:(\\w+):)?(?:\\w+|\\*)");
  private static final Pattern PREFIX_PATTERN = Pattern.compile("(?:^|\\s)(\\w+)");

  public XsltReferenceProvider() {
  }

  @NotNull
  public PsiReference[] getReferencesByElement(@NotNull PsiElement e, @NotNull ProcessingContext context) {
    final PsiElement element = e.getParent();
    if (element instanceof XmlAttribute) {
      final XmlAttribute attribute = (XmlAttribute)element;

      CachedValue<PsiReference[]> cachedValue = attribute.getUserData(CACHED_XSLT_REFS);
      if (cachedValue == null) {
        cachedValue = CachedValuesManager.getManager(element.getProject()).createCachedValue(new ReferenceProvider(attribute), false);
        attribute.putUserData(CACHED_XSLT_REFS, cachedValue);
      }

      final PsiReference[] value = cachedValue.getValue();
      assert value != null;
      return value;
    } else {
      return PsiReference.EMPTY_ARRAY;
    }
  }

  private class ReferenceProvider implements CachedValueProvider<PsiReference[]> {
    private final XmlAttribute myAttribute;

    ReferenceProvider(XmlAttribute attribute) {
      myAttribute = attribute;
    }

    public Result<PsiReference[]> compute() {
      final PsiReference[] referencesImpl = getReferencesImpl(myAttribute);
      final Object[] refs = new PsiElement[referencesImpl.length];
      for (int i = 0; i < refs.length; i++) {
        refs[i] = referencesImpl[i].getElement();
      }
      return new Result<PsiReference[]>(referencesImpl, ArrayUtil.append(refs, myAttribute.getValueElement()));
    }

    private PsiReference[] getReferencesImpl(final XmlAttribute attribute) {
      final PsiReference[] psiReferences;
      final XmlTag tag = attribute.getParent();

      if (XsltSupport.isTemplateCallName(attribute)) {
        psiReferences = createReferencesWithPrefix(attribute, new TemplateReference(attribute));
      } else if (XsltSupport.isTemplateCallParamName(attribute)) {
        final String paramName = attribute.getValue();
        final XmlTag templateCall = PsiTreeUtil.getParentOfType(tag, XmlTag.class);

        if (templateCall != null) {
          if (XsltSupport.isTemplateCall(templateCall)) {
            final XsltCallTemplate call = myXsltElementFactory.wrapElement(templateCall, XsltCallTemplate.class);
            final ResolveUtil.Matcher matcher = new MyParamMatcher(paramName, call);
            psiReferences = new PsiReference[]{ new AttributeReference(attribute, matcher, true) };
          } else if (XsltSupport.isApplyTemplates(templateCall)) {
            final XsltApplyTemplates call = myXsltElementFactory.wrapElement(templateCall, XsltApplyTemplates.class);
            final ResolveUtil.Matcher matcher = new MyParamMatcher2(paramName, call);
            psiReferences = new PsiReference[]{ new ParamReference(attribute, matcher) };
          } else {
            psiReferences = PsiReference.EMPTY_ARRAY;
          }
        } else {
          psiReferences = PsiReference.EMPTY_ARRAY;
        }
      } else if (XsltSupport.isParam(attribute) && isInsideUnnamedTemplate(tag)) {
        final XsltParameter myParam = myXsltElementFactory.wrapElement(tag, XsltParameter.class);
        psiReferences = new PsiReference[]{ new MySelfReference(attribute, myParam) };
      } else if (XsltSupport.isVariableOrParamName(attribute) || XsltSupport.isTemplateName(attribute)) {
        final XsltElement myElement = myXsltElementFactory.wrapElement(tag, XsltElement.class);
        psiReferences = createReferencesWithPrefix(attribute, SelfReference.create(attribute, myElement));
      } else if (XsltSupport.isFunctionName(attribute)) {
        final XsltFunction myElement = myXsltElementFactory.wrapElement(tag, XsltFunction.class);
        psiReferences = createReferencesWithPrefix(attribute, SelfReference.create(attribute, myElement));
      } else if (XsltSupport.isIncludeOrImportHref(attribute)) {
        final String href = attribute.getValue();
        final String resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(href, attribute.getProject());
        //noinspection StringEquality
        if (href == resourceLocation) {
          // not a configured external resource
          if (!URLUtil.containsScheme(href)) {
            // a local file reference
            final FileReferenceSet filereferenceset = new FileReferenceSet(
              href,
              attribute.getValueElement(), 1, XsltReferenceProvider.this, true);
            psiReferences = filereferenceset.getAllReferences();
          } else {
            // external, but unknown resource
            psiReferences = new PsiReference[]{ new ExternalResourceReference(attribute) };
          }
        } else {
          // external, known resource
          psiReferences = new PsiReference[]{ new ExternalResourceReference(attribute) };
        }
      } else if (XsltSupport.isMode(attribute)) {
        psiReferences = ModeReference.create(attribute, XsltSupport.isTemplate(tag, false));
      } else if ((attribute.getLocalName().equals("extension-element-prefixes") ||
                  attribute.getLocalName().equals("exclude-result-prefixes")) && XsltSupport.isXsltRootTag(tag)) {
        psiReferences = createPrefixReferences(attribute, PREFIX_PATTERN);
      } else if (attribute.getLocalName().equals("stylesheet-prefix") && tag.getLocalName().equals("namespace-alias")) {
        psiReferences = createPrefixReferences(attribute, PREFIX_PATTERN);
      } else if ("elements".equals(attribute.getLocalName())) {
        if (("strip-space".equals(tag.getLocalName()) || "preserve-space".equals(tag.getLocalName()))) {
          psiReferences = createPrefixReferences(attribute, ELEMENT_PATTERN);
        } else {
          psiReferences = PsiReference.EMPTY_ARRAY;
        }
      } else {
        psiReferences = PsiReference.EMPTY_ARRAY;
      }

      return psiReferences;
    }

    private PsiReference[] createReferencesWithPrefix(XmlAttribute attribute, PsiReference reference) {
      if (attribute.getValue().contains(":")) {
        return new PsiReference[]{ new PrefixReference(attribute), reference };
      } else {
        return new PsiReference[]{ reference };
      }
    }

    private class MySelfReference extends SelfReference {
      private final XsltParameter myParam;
      private final XmlTag myTag;

      public MySelfReference(XmlAttribute attribute, XsltParameter param) {
        super(attribute, param);
        myParam = param;
        myTag = param.getTag();
      }


      public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
        if (!newElementName.equals(myParam.getName())) {
          myParam.setName(newElementName);
        }
        final XmlAttribute attribute = myParam.getNameAttribute();
        assert attribute != null;
        //noinspection ConstantConditions
        return attribute.getValueElement();
      }

      public boolean isReferenceTo(PsiElement element) {
        // self-reference is only a trick to enable rename/find usages etc. but it shouldn't actually
        // refer to itself because this would list the element to be renamed/searched for twice
        assert !super.isReferenceTo(element);

        if (element == myParam) return false;
        if (!(element instanceof XsltParameter)) return false;

        final XsltParameter param = ((XsltParameter)element);
        final String name = param.getName();
        if (name == null || !name.equals(myParam.getName())) return false;

        final XsltTemplate template = XsltCodeInsightUtil.getTemplate(myTag, false);
        final XsltTemplate myTemplate = XsltCodeInsightUtil.getTemplate(param.getTag(), false);
        if (template == myTemplate) return true;
        if (template == null || myTemplate == null) return false;

        if (!Comparing.equal(template.getMode(), myTemplate.getMode())) {
          return false;
        }

        final XmlFile xmlFile = (XmlFile)element.getContainingFile();
        final XmlFile myFile = (XmlFile)myParam.getContainingFile();
        if (myFile == xmlFile) return true;

        return XsltIncludeIndex.isReachableFrom(myFile, xmlFile);
      }
    }
  }

  private static PsiReference[] createPrefixReferences(XmlAttribute attribute, Pattern pattern) {
    final Matcher matcher = pattern.matcher(attribute.getValue());

    if (matcher.find()) {
      final List<PsiReference> refs = new SmartList<PsiReference>();
      do {
        final int start = matcher.start(1);
        if (start >= 0) {
          refs.add(new PrefixReference(attribute, TextRange.create(start, matcher.end(1))));
        }
      }
      while (matcher.find());

      return refs.toArray(new PsiReference[refs.size()]);
    }
    return PsiReference.EMPTY_ARRAY;
  }

  private static boolean isInsideUnnamedTemplate(XmlTag tag) {
    final XmlTag t = XsltCodeInsightUtil.getTemplateTag(tag, false, false);
    return t != null && t.getAttribute("name", null) == null;
  }

  static class MyParamMatcher extends NamedTemplateMatcher {
    private final XsltCallTemplate myCall;
    private final String myParamName;
    private String[] myExcludedNames = ArrayUtil.EMPTY_STRING_ARRAY;

    MyParamMatcher(String paramName, XsltCallTemplate call) {
      super(XsltCodeInsightUtil.getDocument(call), call.getTemplateName());
      myCall = call;
      myParamName = paramName;
    }

    private MyParamMatcher(String paramName, XsltCallTemplate call, String[] excludedNames) {
      super(getDocument(call), call.getTemplateName());
      myCall = call;
      myParamName = paramName;
      myExcludedNames = excludedNames;
    }

    private static XmlDocument getDocument(XsltCallTemplate call) {
      final XsltTemplate template = call.getTemplate();
      return XsltCodeInsightUtil.getDocument(template != null ? template : call);
    }

    @Override
    protected ResolveUtil.Matcher changeDocument(XmlDocument document) {
      return new MyParamMatcher(myParamName, myCall, myExcludedNames);
    }

    @Override
    protected Result matchImpl(XmlTag element) {
      if (matches(element)) {
        return Result.create(new ParamMatcher(element, myExcludedNames, myParamName));
      }
      return null;
    }

    @Override
    public ResolveUtil.Matcher variantMatcher() {
      final PsiElement[] suppliedArgs = ResolveUtil.collect(new ArgumentMatcher(myCall));
      final String[] excludedNames = new String[suppliedArgs.length];
      for (int i = 0; i < suppliedArgs.length; i++) {
        excludedNames[i] = ((XmlTag)suppliedArgs[i]).getAttributeValue("name");
      }
      return new MyParamMatcher(null, myCall, excludedNames);
    }
  }

  static class MyParamMatcher2 extends MatchTemplateMatcher {
    private final String myParamName;
    private final XsltApplyTemplates myCall;
    private String[] myExcludedNames = ArrayUtil.EMPTY_STRING_ARRAY;

    MyParamMatcher2(String paramName, XsltApplyTemplates call) {
      super(XsltCodeInsightUtil.getDocument(call), call.getMode());
      myParamName = paramName;
      myCall = call;
    }

    private MyParamMatcher2(String paramName, XsltApplyTemplates call, String[] excludedNames) {
      this(paramName, call);
      myExcludedNames = excludedNames;
    }

    @Override
    protected Result matchImpl(XmlTag element) {
      if (matches(element)) {
        return Result.create(new ParamMatcher(element, myExcludedNames, myParamName));
      }
      return null;
    }

    @Override
    protected ResolveUtil.Matcher changeDocument(XmlDocument document) {
      return new MyParamMatcher2(myParamName, myCall);
    }

    @Override
    public ResolveUtil.Matcher variantMatcher() {
      final PsiElement[] suppliedArgs = ResolveUtil.collect(new ArgumentMatcher(myCall));
      final String[] excludedNames = new String[suppliedArgs.length];
      for (int i = 0; i < suppliedArgs.length; i++) {
        excludedNames[i] = ((XmlTag)suppliedArgs[i]).getAttributeValue("name");
      }
      return new MyParamMatcher2(null, myCall, excludedNames);
    }
  }
}
