/*
 * Copyright 2005 Sascha Weinreuter
 *
 * 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 org.intellij.lang.xpath.xslt.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.navigation.PsiElementNavigationItem;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import org.intellij.lang.xpath.completion.CompletionLists;
import org.intellij.lang.xpath.context.ContextProvider;
import org.intellij.lang.xpath.context.XPathVersion;
import org.intellij.lang.xpath.psi.XPathElement;
import org.intellij.lang.xpath.psi.XPathElementVisitor;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.psi.XsltElement;
import org.intellij.lang.xpath.xslt.psi.XsltElementFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.lang.reflect.*;

abstract class XsltElementImpl extends LightElement implements Iconable, PsiElementNavigationItem, XsltElement, ItemPresentation {

    protected final @NotNull XmlTag myElement;
    protected final XsltElementFactory myElementFactory;

    private final int myHashCode;
    private PsiElement myNavigationElement;

    protected XsltElementImpl(XmlTag target) {
        super(target.getManager(), XsltLanguage.INSTANCE);
        myElement = target;
        myHashCode = myElement.hashCode();
        myElementFactory = XsltElementFactory.getInstance();
    }

    public PsiElement copy() {
        return myElementFactory.wrapElement((XmlTag)myElement.copy(), getClass());
    }

    public String getText() {
        return myElement.getText();
    }

    public XmlTag getTag() {
        return myElement;
    }

    @Override
    @Nullable
    public final ItemPresentation getPresentation() {
        return this;
    }

    @Nullable
    public Icon getIcon(boolean open) {
        return getIcon(0);
    }

    @Nullable
    public String getLocationString() {
        return "(in " + getContainingFile().getName() + ")";
    }

    @SuppressWarnings({"ConstantConditions"})
    public String getPresentableText() {
        return getName();
    }

    @Override
    public PsiElement getTargetElement() {
        return myElement;
    }

    @Nullable
    public String getName() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.getValue() : null;
    }

    public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
        assert myElement.isValid();

        myElement.setAttribute("name", name);
        return this;
    }

    @NotNull
    @Override
    @SuppressWarnings({ "RawUseOfParameterizedType" })
    public PsiElement getNavigationElement() {
        if (myNavigationElement == null && myElement.isValid()) {
            final Class[] allInterfaces = CompletionLists.getAllInterfaces(myElement.getClass());
            myNavigationElement = (PsiElement)Proxy.newProxyInstance(getClass().getClassLoader(), allInterfaces, new InvocationHandler() {
                @Nullable
                @SuppressWarnings({"StringEquality", "AutoBoxing", "AutoUnboxing"})
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    try {
                        final XmlAttributeValue nameElement = XsltElementImpl.this.getNameElement();
                        if (method.getName() == "navigate") {
                            assert nameElement != null;

                            ((NavigationItem)nameElement).navigate((Boolean)args[0]);

                            return null;
                        } else if (method.getName() == "canNavigate") {
                            return nameElement != null && nameElement instanceof NavigationItem && ((NavigationItem)nameElement).canNavigate();
                        } else if (method.getName() == "getTextOffset") {
                            return nameElement != null ? nameElement.getTextOffset() : myElement.getTextOffset();
                        }
                        return method.invoke(myElement, args);
                    } catch (InvocationTargetException e1) {
                        throw e1.getTargetException();
                    }
                }
            });
        }
        return myElement.isValid() ? myNavigationElement : this;
    }

    @Nullable
    public XmlAttribute getNameAttribute() {
        return myElement.getAttribute("name", null);
    }

    @Nullable
    public PsiElement getNameIdentifier() {
        final XmlAttribute nameAttribute = getNameAttribute();
        return nameAttribute != null ? XsltSupport.getAttValueToken(nameAttribute) : null;
    }

    @Nullable
    private XmlAttributeValue getNameElement() {
        final XmlAttribute attribute = getNameAttribute();
        if (attribute != null) {
            final XmlAttributeValue valueElement = attribute.getValueElement();
            return valueElement != null ? valueElement : null;
        }
        return null;
    }

    @Override
    public PsiElement getOriginalElement() {
        return myElement.getOriginalElement();
    }

    @Override
    public boolean isValid() {
        return myElement.isValid();
    }

    @Override
    @NotNull
    public Language getLanguage() {
        return XsltLanguage.INSTANCE;
    }

    @Override
    public void navigate(boolean b) {
        final XmlAttributeValue nameElement = getNameElement();
        assert nameElement != null;
        ((NavigationItem)nameElement).navigate(b);
    }

    @Override
    public boolean canNavigate() {
        final XmlAttributeValue nameElement = getNameElement();
        return myElement.isValid() && nameElement instanceof NavigationItem && ((NavigationItem)nameElement).canNavigate();
    }

    @Override
    public boolean canNavigateToSource() {
        return canNavigate();
    }

    public void accept(@NotNull XPathElementVisitor visitor) {
      visitor.visitXPathElement((XPathElement)this);
    }

    public void accept(@NotNull PsiElementVisitor visitor) {
      if (visitor instanceof XPathElementVisitor && this instanceof XPathElement) {
        accept((XPathElementVisitor)visitor);
      } else {
        myElement.accept(visitor);
      }
    }

    @Override
    public int hashCode() {
        return myHashCode;
    }

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

        final XsltElementImpl that = (XsltElementImpl)o;

        return myElement.equals(that.myElement);
    }

    @Override
    public PsiFile getContainingFile() {
        return myElement.getContainingFile();
    }

    @Override
    public boolean isWritable() {
        return myElement.isWritable();
    }

    @Override
    public boolean isPhysical() {
        return myElement.isPhysical();
    }

    @Override
    public PsiElement getParent() {
//        final XmlTag parent = PsiTreeUtil.getParentOfType(myElement.getParent(), XmlTag.class);
//        return parent != null ?
//                XsltSupport.isXsltTag(parent) ? myElementFactory.wrapElement(parent) : parent
//                : null;

        return myElement.getParent(); // TODO: return XSLT object
    }

    @Override
    @NotNull
    public PsiElement[] getChildren() {
        return myElement.getChildren(); // TODO: return XSLT objects
    }

    @Override
    public TextRange getTextRange() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.getTextRange() : myElement.getTextRange();
    }

    @Override
    public int getStartOffsetInParent() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.getStartOffsetInParent() : myElement.getStartOffsetInParent();
    }

    @Override
    @NotNull
    public char[] textToCharArray() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.textToCharArray() : myElement.textToCharArray();
    }

    @Override
    public int getTextOffset() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.getTextOffset() : myElement.getTextOffset();
    }

    @Override
    public ASTNode getNode() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.getNode() : myElement.getNode();
    }

    @Override
    @NotNull
    public PsiReference[] getReferences() {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.getReferences() : myElement.getReferences();
    }

    @Override
    public boolean textMatches(@NotNull CharSequence charSequence) {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.textMatches(charSequence) : myElement.textMatches(charSequence);
    }

    @Override
    public boolean textMatches(@NotNull PsiElement psiElement) {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.textMatches(psiElement) : myElement.textMatches(psiElement);
    }

    @Override
    public PsiElement findElementAt(int i) {
        final XmlAttributeValue nameElement = getNameElement();
        return nameElement != null ? nameElement.findElementAt(i) : myElement.findElementAt(i);
    }

    @Override
    public void delete() throws IncorrectOperationException {
        myElement.delete();
    }

    protected static <S, T extends S> T[] convertArray(S[] elements, Class<T> aClass) {
        //noinspection unchecked
        final T[] t = (T[])Array.newInstance(aClass, elements.length);
        //noinspection SuspiciousSystemArraycopy
        System.arraycopy(elements, 0, t, 0, elements.length);
        return t;
    }

  public ContextProvider getXPathContext() {
    throw new UnsupportedOperationException();
  }

  public XPathVersion getXPathVersion() {
    throw new UnsupportedOperationException();
  }
}
