/*
 * Copyright 2000-2014 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.intellij.util.xml.impl;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.xml.*;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @author peter
 */
public class StaticGenericInfoBuilder {
  private static final Set ADDER_PARAMETER_TYPES = new THashSet<Class>(Arrays.asList(Class.class, int.class));
  private static final Logger LOG = Logger.getInstance(StaticGenericInfoBuilder.class);
  private final Class myClass;
  private final MultiValuesMap<XmlName, JavaMethod> myCollectionGetters = new MultiValuesMap<XmlName, JavaMethod>();
  final MultiValuesMap<XmlName, JavaMethod> collectionAdders = new MultiValuesMap<XmlName, JavaMethod>();
  final MultiValuesMap<XmlName, JavaMethod> collectionClassAdders = new MultiValuesMap<XmlName, JavaMethod>();
  final MultiValuesMap<XmlName, JavaMethod> collectionIndexAdders = new MultiValuesMap<XmlName, JavaMethod>();
  final MultiValuesMap<XmlName, JavaMethod> collectionIndexClassAdders = new MultiValuesMap<XmlName, JavaMethod>();
  final MultiValuesMap<XmlName, JavaMethod> collectionClassIndexAdders = new MultiValuesMap<XmlName, JavaMethod>();
  private final Map<XmlName, Type> myCollectionChildrenTypes = new THashMap<XmlName, Type>();
  private final Map<JavaMethodSignature, String[]> myCompositeCollectionGetters = new THashMap<JavaMethodSignature, String[]>();
  private final Map<JavaMethodSignature, Pair<String,String[]>> myCompositeCollectionAdders = new THashMap<JavaMethodSignature, Pair<String,String[]>>();
  private final FactoryMap<XmlName, TIntObjectHashMap<Collection<JavaMethod>>> myFixedChildrenGetters = new FactoryMap<XmlName, TIntObjectHashMap<Collection<JavaMethod>>>() {
    @Override
    protected TIntObjectHashMap<Collection<JavaMethod>> create(final XmlName key) {
      return new TIntObjectHashMap<Collection<JavaMethod>>();
    }
  };
  private final Map<JavaMethodSignature, AttributeChildDescriptionImpl> myAttributes = new THashMap<JavaMethodSignature, AttributeChildDescriptionImpl>();

  private boolean myValueElement;
  private JavaMethod myNameValueGetter;
  private JavaMethod myCustomChildrenGetter;

  public StaticGenericInfoBuilder(final Class aClass) {
    myClass = aClass;

    final Set<JavaMethod> methods = new LinkedHashSet<JavaMethod>();
    InvocationCache invocationCache = DomApplicationComponent.getInstance().getInvocationCache(myClass);
    for (final Method method : ReflectionUtil.getClassPublicMethods(myClass)) {
      methods.add(invocationCache.getInternedMethod(method));
    }
    for (final JavaMethod method : methods) {
      if (DomImplUtil.isGetter(method) && method.getAnnotation(NameValue.class) != null) {
        myNameValueGetter = method;
        break;
      }
    }

    {
      final Class implClass = DomApplicationComponent.getInstance().getImplementation(myClass);
      if (implClass != null) {
        for (Method method : ReflectionUtil.getClassPublicMethods(implClass)) {
          final int modifiers = method.getModifiers();
          if (!Modifier.isAbstract(modifiers) &&
              !Modifier.isVolatile(modifiers) &&
              new JavaMethodSignature(method).findMethod(myClass) != null) {
            methods.remove(invocationCache.getInternedMethod(method));
          }
        }
      }
    }

    for (Iterator<JavaMethod> iterator = methods.iterator(); iterator.hasNext();) {
      final JavaMethod method = iterator.next();
      if (isCoreMethod(method) || DomImplUtil.isTagValueSetter(method) || method.getAnnotation(PropertyAccessor.class) != null) {
        iterator.remove();
      }
    }

    for (Iterator<JavaMethod> iterator = methods.iterator(); iterator.hasNext();) {
      final JavaMethod method = iterator.next();
      if (DomImplUtil.isGetter(method) && processGetterMethod(method)) {
        iterator.remove();
      }
    }

    for (Iterator<JavaMethod> iterator = methods.iterator(); iterator.hasNext();) {
      final JavaMethod method = iterator.next();
      final SubTagsList subTagsList = method.getAnnotation(SubTagsList.class);
      if (subTagsList != null && method.getName().startsWith("add")) {
        final String localName = subTagsList.tagName();
        assert StringUtil.isNotEmpty(localName);
        final String[] set = subTagsList.value();
        assert Arrays.asList(set).contains(localName);
        myCompositeCollectionAdders.put(method.getSignature(), Pair.create(localName, set));
        iterator.remove();
      }
      else if (isAddMethod(method)) {
        final XmlName xmlName = extractTagName(method, "add");
        if (myCollectionGetters.containsKey(xmlName)) {
          MultiValuesMap<XmlName, JavaMethod> adders = getAddersMap(method);
          if (adders != null) {
            adders.put(xmlName, method);
            iterator.remove();
          }
        }
      }
    }

    //noinspection ConstantIfStatement
    if (false) {
      if (!methods.isEmpty()) {
        StringBuilder sb = new StringBuilder(myClass + " should provide the following implementations:");
        for (JavaMethod method : methods) {
          sb.append("\n  ");
          sb.append(method);
        }
        assert false : sb.toString();
        //System.out.println(sb.toString());
      }
    }
  }

  @Nullable
  private MultiValuesMap<XmlName, JavaMethod> getAddersMap(final JavaMethod method) {
    final Class<?>[] parameterTypes = method.getParameterTypes();
    switch (parameterTypes.length) {
      case 0:
        return collectionAdders;
      case 1:
        if (Class.class.equals(parameterTypes[0])) return collectionClassAdders;
        if (isInt(parameterTypes[0])) return collectionIndexAdders;
        break;
      case 2:
        if (isIndexClassAdder(parameterTypes[0], parameterTypes[1])) return collectionIndexClassAdders;
        if (isIndexClassAdder(parameterTypes[1], parameterTypes[0])) return collectionClassIndexAdders;
    }
    return null;
  }

  private static boolean isIndexClassAdder(final Class<?> first, final Class<?> second) {
    return isInt(first) && second.equals(Class.class);
  }

  private static boolean isInt(final Class<?> aClass) {
    return aClass.equals(int.class) || aClass.equals(Integer.class);
  }

  private boolean isAddMethod(JavaMethod method) {
    final XmlName tagName = extractTagName(method, "add");
    if (tagName == null) return false;

    final Type type = myCollectionChildrenTypes.get(tagName);
    if (type == null || !ReflectionUtil.getRawType(type).isAssignableFrom(method.getReturnType())) return false;

    return ADDER_PARAMETER_TYPES.containsAll(Arrays.asList(method.getParameterTypes()));
  }

  @Nullable
  private XmlName extractTagName(JavaMethod method, @NonNls String prefix) {
    final String name = method.getName();
    if (!name.startsWith(prefix)) return null;

    final SubTagList subTagAnnotation = method.getAnnotation(SubTagList.class);
    if (subTagAnnotation != null && !StringUtil.isEmpty(subTagAnnotation.value())) {
      return DomImplUtil.createXmlName(subTagAnnotation.value(), method);
    }

    final String tagName = getNameStrategy(false).convertName(name.substring(prefix.length()));
    return StringUtil.isEmpty(tagName) ? null : DomImplUtil.createXmlName(tagName, method);
  }

  private static boolean isDomElement(final Type type) {
    return type != null && DomElement.class.isAssignableFrom(ReflectionUtil.getRawType(type));
  }

  private boolean processGetterMethod(final JavaMethod method) {
    if (DomImplUtil.isTagValueGetter(method)) {
      myValueElement = true;
      return true;
    }

    final Class returnType = method.getReturnType();
    final boolean isAttributeValueMethod = GenericAttributeValue.class.isAssignableFrom(returnType);
    final JavaMethodSignature signature = method.getSignature();
    final Attribute annotation = method.getAnnotation(Attribute.class);
    final boolean isAttributeMethod = annotation != null || isAttributeValueMethod;
    if (annotation != null) {
      assert
        isAttributeValueMethod || GenericAttributeValue.class.isAssignableFrom(returnType) :
        method + " should return GenericAttributeValue";
    }
    if (isAttributeMethod) {
      final String s = annotation == null ? null : annotation.value();
      String attributeName = StringUtil.isEmpty(s) ? getNameFromMethod(method, true) : s;
      assert attributeName != null && StringUtil.isNotEmpty(attributeName) : "Can't guess attribute name from method name: " + method.getName();
      final XmlName attrName = DomImplUtil.createXmlName(attributeName, method);
      myAttributes.put(signature, new AttributeChildDescriptionImpl(attrName, method));
      return true;
    }

    if (isDomElement(returnType)) {
      final String qname = getSubTagName(method);
      if (qname != null) {
        final XmlName xmlName = DomImplUtil.createXmlName(qname, method);
        Type collectionType = myCollectionChildrenTypes.get(xmlName);
        if (collectionType != null) {
          LOG.error("Collection (" + collectionType + ") and fixed children cannot intersect: " + qname + " for " + myClass);
        }
        int index = 0;
        final SubTag subTagAnnotation = method.getAnnotation(SubTag.class);
        if (subTagAnnotation != null && subTagAnnotation.index() != 0) {
          index = subTagAnnotation.index();
        }
        final TIntObjectHashMap<Collection<JavaMethod>> map = myFixedChildrenGetters.get(xmlName);
        Collection<JavaMethod> methods = map.get(index);
        if (methods == null) {
          map.put(index, methods = new SmartList<JavaMethod>());
        }
        methods.add(method);
        return true;
      }
    }

    final Type type = DomReflectionUtil.extractCollectionElementType(method.getGenericReturnType());
    if (isDomElement(type)) {
      final CustomChildren customChildren = method.getAnnotation(CustomChildren.class);
      if (customChildren != null) {
        myCustomChildrenGetter = method;
        return true;
      }

      final SubTagsList subTagsList = method.getAnnotation(SubTagsList.class);
      if (subTagsList != null) {
        myCompositeCollectionGetters.put(signature, subTagsList.value());
        return true;
      }

      final String qname = getSubTagNameForCollection(method);
      if (qname != null) {
        XmlName xmlName = DomImplUtil.createXmlName(qname, type, method);
        assert !myFixedChildrenGetters.containsKey(xmlName) : "Collection and fixed children cannot intersect: " + qname;
        myCollectionChildrenTypes.put(xmlName, type);
        myCollectionGetters.put(xmlName, method);
        return true;
      }
    }

    return false;
  }

  private static boolean isCoreMethod(final JavaMethod method) {
    if (method.getSignature().findMethod(DomElement.class) != null) return true;

    final Class<?> aClass = method.getDeclaringClass();
    return aClass.equals(GenericAttributeValue.class) || aClass.equals(GenericDomValue.class) && "getConverter".equals(method.getName());
  }

  @Nullable
  private String getSubTagName(final JavaMethod method) {
    final SubTag subTagAnnotation = method.getAnnotation(SubTag.class);
    if (subTagAnnotation == null || StringUtil.isEmpty(subTagAnnotation.value())) {
      return getNameFromMethod(method, false);
    }
    return subTagAnnotation.value();
  }

  @Nullable
  private String getSubTagNameForCollection(final JavaMethod method) {
    final SubTagList subTagList = method.getAnnotation(SubTagList.class);
    if (subTagList == null || StringUtil.isEmpty(subTagList.value())) {
      final String propertyName = getPropertyName(method);
      if (propertyName != null) {
        final String singular = StringUtil.unpluralize(propertyName);
        assert singular != null : "Can't unpluralize: " + propertyName;
        return getNameStrategy(false).convertName(singular);
      }
      else {
        return null;
      }
    }
    return subTagList.value();
  }

  @Nullable
  private String getNameFromMethod(final JavaMethod method, boolean isAttribute) {
    final String propertyName = getPropertyName(method);
    return propertyName == null ? null : getNameStrategy(isAttribute).convertName(propertyName);
  }

  @Nullable
  private static String getPropertyName(JavaMethod method) {
    return StringUtil.getPropertyName(method.getMethodName());
  }

  @NotNull
  private DomNameStrategy getNameStrategy(boolean isAttribute) {
    final DomNameStrategy strategy = DomImplUtil.getDomNameStrategy(ReflectionUtil.getRawType(myClass), isAttribute);
    return strategy != null ? strategy : DomNameStrategy.HYPHEN_STRATEGY;
  }

  final JavaMethod getCustomChildrenGetter() {
    return myCustomChildrenGetter;
  }

  final Map<JavaMethodSignature, AttributeChildDescriptionImpl> getAttributes() {
    return myAttributes;
  }

  final Map<JavaMethodSignature, Pair<FixedChildDescriptionImpl, Integer>> getFixedGetters() {
    final Map<JavaMethodSignature, Pair<FixedChildDescriptionImpl, Integer>> map = new THashMap<JavaMethodSignature, Pair<FixedChildDescriptionImpl, Integer>>();
    final Set<XmlName> names = myFixedChildrenGetters.keySet();
    for (final XmlName name : names) {
      final TIntObjectHashMap<Collection<JavaMethod>> map1 = myFixedChildrenGetters.get(name);
      int max = 0;
      final int[] ints = map1.keys();
      for (final int i : ints) {
        max = Math.max(max, i);
      }
      int count = max + 1;
      final Collection<JavaMethod>[] getters = new Collection[count];
      for (final int i : ints) {
        getters[i] = map1.get(i);
      }
      final FixedChildDescriptionImpl description = new FixedChildDescriptionImpl(name, map1.get(0).iterator().next().getGenericReturnType(), count, getters);
      for (int i = 0; i < getters.length; i++) {
        final Collection<JavaMethod> collection = getters[i];
        for (final JavaMethod method : collection) {
          map.put(method.getSignature(), Pair.create(description, i));
        }
      }
    }
    return map;
  }

  final Map<JavaMethodSignature, CollectionChildDescriptionImpl> getCollectionGetters() {
    final Map<JavaMethodSignature, CollectionChildDescriptionImpl> getters = new THashMap<JavaMethodSignature, CollectionChildDescriptionImpl>();
    for (final XmlName xmlName : myCollectionGetters.keySet()) {
      final Collection<JavaMethod> collGetters = myCollectionGetters.get(xmlName);
      final JavaMethod method = collGetters.iterator().next();


      final CollectionChildDescriptionImpl description = new CollectionChildDescriptionImpl(xmlName, DomReflectionUtil.extractCollectionElementType(method.getGenericReturnType()),
                                                                                            collGetters
      );
      for (final JavaMethod getter : collGetters) {
        getters.put(getter.getSignature(), description);
      }
    }

    return getters;
  }

  final Map<JavaMethodSignature, Pair<String, String[]>> getCompositeCollectionAdders() {
    return myCompositeCollectionAdders;
  }

  final Map<JavaMethodSignature, String[]> getCompositeCollectionGetters() {
    return myCompositeCollectionGetters;
  }

  public JavaMethod getNameValueGetter() {
    return myNameValueGetter;
  }

  public boolean isValueElement() {
    return myValueElement;
  }
}
