package de.espend.idea.php.annotation.reference;

import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
import com.jetbrains.php.lang.documentation.phpdoc.parser.PhpDocElementTypes;
import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import de.espend.idea.php.annotation.util.AnnotationUtil;
import org.jetbrains.annotations.NotNull;

public class DocTagNameAnnotationReferenceContributor extends PsiReferenceContributor {

    @Override
    public void registerReferenceProviders(PsiReferenceRegistrar psiReferenceRegistrar) {

        // both dont get called on @Template
        // PlatformPatterns.psiElement()
        // PlatformPatterns.psiElement().withElementType(PhpDocElementTypes.DOC_TAG_NAME)

        psiReferenceRegistrar.registerReferenceProvider(
            PlatformPatterns.psiElement().withElementType(PhpDocElementTypes.DOC_TAG_NAME),
            new PsiReferenceProvider() {
                @NotNull
                @Override
                public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {

                    if(!(element instanceof PhpDocTag)) {
                        return new PsiReference[0];
                    }

                    return new PsiReference[] {
                        new PhpDocTagReference((PhpDocTag) element)
                    };
                }
            }

        );

    }

    public class PhpDocTagReference extends PsiPolyVariantReferenceBase<PhpDocTag> {

        public PhpDocTagReference(PhpDocTag psiElement) {
            super(psiElement);
        }

        @Override
        public boolean isReferenceTo(PsiElement element) {

            // implemented this when usable
            /**
            if (element instanceof PhpUse) {
                final ResolveResult[] results = multiResolve(false);
                for (ResolveResult result : results) {
                    if(result.isValidResult() && result.getElement() == element) {
                        return true;
                    }
                }
            }
            */

            return false;
        }

        @NotNull
        @Override
        public ResolveResult[] multiResolve(boolean b) {
            PhpClass phpClass = AnnotationUtil.getAnnotationReference(getElement());
            if(phpClass == null) {
                return new ResolveResult[0];
            }

            return new ResolveResult[] { new PsiElementResolveResult(phpClass) };
        }

        @NotNull
        @Override
        public Object[] getVariants() {
            return new Object[0];
        }
    }

}

@@ -673,172 +673,88 @@
  // 
-both dont
+now we
  get 
+a 
 call
-ed on @Template%0A        // PlatformPatterns.psiElement()%0A        // PlatformPatterns.psiElement().withElementType(PhpDocElementTypes.DOC_TAG_NAME)
+ now, but also an error %22Cannot find manipulator for PhpDocTag%22
 %0A%0A  
@@ -852,57 +852,23 @@
 ent(
-).withElementType(PhpDocElementTypes.DOC_TAG_NAME
+PhpDocTag.class
 ),%0A 
@@ -1319,20 +1319,8 @@
 nce(
-(PhpDocTag) 
 elem
@@ -1472,24 +1472,25 @@
 ceBase%3CP
-hpDocTag
+siElement
 %3E %7B%0A%0A   
@@ -1521,24 +1521,25 @@
 erence(P
-hpDocTag
+siElement
  psiElem
@@ -1579,32 +1579,43 @@
 nt);%0A        %7D%0A%0A
+        /*%0A
         @Overrid
@@ -2083,22 +2083,8 @@
   %7D%0A
-            */
 %0A%0A  
@@ -2108,32 +2108,35 @@
 false;%0A        %7D
+ */
 %0A%0A        @NotNu
@@ -2209,24 +2209,140 @@
 oolean b) %7B%0A
+%0A            if(!(getElement() instanceof PhpDocTag)) %7B%0A                return new ResolveResult%5B0%5D;%0A            %7D%0A%0A
             
@@ -2399,16 +2399,28 @@
 ference(
+(PhpDocTag) 
 getEleme

update doctag reference to support psi pattern of 131.332, but its still not working