/*
 * Copyright 2000-2013 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.compiler.classFilesIndex.chainsSearch;

import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.completion.JavaChainLookupElement;
import com.intellij.compiler.classFilesIndex.chainsSearch.context.ChainCompletionContext;
import com.intellij.compiler.classFilesIndex.chainsSearch.context.ContextRelevantStaticMethod;
import com.intellij.compiler.classFilesIndex.chainsSearch.context.ContextRelevantVariableGetter;
import com.intellij.compiler.classFilesIndex.chainsSearch.completion.lookup.ChainCompletionNewVariableLookupElement;
import com.intellij.compiler.classFilesIndex.chainsSearch.completion.lookup.WeightableChainLookupElement;
import com.intellij.compiler.classFilesIndex.chainsSearch.completion.lookup.sub.GetterLookupSubLookupElement;
import com.intellij.compiler.classFilesIndex.chainsSearch.completion.lookup.sub.SubLookupElement;
import com.intellij.compiler.classFilesIndex.chainsSearch.completion.lookup.sub.VariableSubLookupElement;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.psi.*;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static com.intellij.compiler.classFilesIndex.chainsSearch.completion.lookup.ChainCompletionLookupElementUtil.createLookupElement;
import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;

/**
 * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
 */
public class MethodsChainLookupRangingHelper {

  public static List<LookupElement> chainsToWeightableLookupElements(final List<MethodsChain> chains,
                                                                     final ChainCompletionContext context) {
    final CachedRelevantStaticMethodSearcher staticMethodSearcher = new CachedRelevantStaticMethodSearcher(context);
    final List<LookupElement> lookupElements = new ArrayList<LookupElement>(chains.size());
    for (final MethodsChain chain : chains) {
      final LookupElement lookupElement = chainToWeightableLookupElement(chain, context, staticMethodSearcher);
      if (lookupElement != null) {
        lookupElements.add(lookupElement);
      }
    }
    return lookupElements;
  }

  @SuppressWarnings("ConstantConditions")
  @Nullable
  private static LookupElement chainToWeightableLookupElement(final MethodsChain chain,
                                                              final ChainCompletionContext context,
                                                              final CachedRelevantStaticMethodSearcher staticMethodSearcher) {
    final int chainSize = chain.size();
    assert chainSize != 0;
    final int lastMethodWeight = chain.getChainWeight();
    int unreachableParametersCount = 0;
    int notMatchedStringVars = 0;
    int matchedParametersInContext = 0;
    Boolean isFirstMethodStatic = null;
    Boolean hasCallingVariableInContext = null;
    LookupElement chainLookupElement = null;
    PsiClass newVariableClass = null;
    final NullableNotNullManager nullableNotNullManager = NullableNotNullManager.getInstance(context.getProject());

    for (final PsiMethod[] psiMethods : chain.getPath()) {
      final PsiMethod method =
        MethodChainsSearchUtil.getMethodWithMinNotPrimitiveParameters(psiMethods, Collections.singleton(context.getTarget().getClassQName()));
      if (method == null) {
        return null;
      }
      if (isFirstMethodStatic == null) {
        isFirstMethodStatic = psiMethods[0].hasModifierProperty(PsiModifier.STATIC);
      }
      final PsiClass qualifierClass;
      final boolean isHead = chainLookupElement == null;
      if (isHead) {
        final String qualifierClassName = chain.getQualifierClassName();
        qualifierClass = JavaPsiFacade.getInstance(context.getProject()).
          findClass(qualifierClassName, context.getResolveScope());
      }
      else {
        qualifierClass = null;
      }

      final MethodProcResult procResult = processMethod(method, qualifierClass, isHead, lastMethodWeight, context, staticMethodSearcher,
                                                        nullableNotNullManager);
      if (procResult == null) {
        return null;
      }
      if (hasCallingVariableInContext == null) {
        hasCallingVariableInContext = procResult.hasCallingVariableInContext();
      }
      if (isHead && procResult.isIntroduceNewVariable()) {
        newVariableClass = qualifierClass;
      }
      matchedParametersInContext += procResult.getMatchedParametersInContext();
      unreachableParametersCount += procResult.getUnreachableParametersCount();
      notMatchedStringVars += procResult.getNotMatchedStringVars();
      chainLookupElement =
        isHead ? procResult.getLookupElement() : new JavaChainLookupElement(chainLookupElement, procResult.getLookupElement());
    }

    if (newVariableClass != null) {
      chainLookupElement = ChainCompletionNewVariableLookupElement.create(newVariableClass, chainLookupElement);
    }

    final ChainRelevance relevance =
      new ChainRelevance(chainSize, lastMethodWeight, unreachableParametersCount, notMatchedStringVars, hasCallingVariableInContext,
                         isFirstMethodStatic, matchedParametersInContext);

    return new WeightableChainLookupElement(chainLookupElement, relevance);
  }


  @Nullable
  private static MethodProcResult processMethod(@NotNull final PsiMethod method,
                                                @Nullable final PsiClass qualifierClass,
                                                final boolean isHeadMethod,
                                                final int weight,
                                                final ChainCompletionContext context,
                                                final CachedRelevantStaticMethodSearcher staticMethodSearcher,
                                                final NullableNotNullManager nullableNotNullManager) {
    int unreachableParametersCount = 0;
    int notMatchedStringVars = 0;
    int matchedParametersInContext = 0;
    boolean hasCallingVariableInContext = false;
    boolean introduceNewVariable = false;
    final PsiParameterList parameterList = method.getParameterList();
    final TIntObjectHashMap<SubLookupElement> parametersMap = new TIntObjectHashMap<SubLookupElement>(parameterList.getParametersCount());
    final PsiParameter[] parameters = parameterList.getParameters();
    for (int i = 0; i < parameters.length; i++) {
      final PsiParameter parameter = parameters[i];
      final String typeQName = parameter.getType().getCanonicalText();
      if (JAVA_LANG_STRING.equals(typeQName)) {
        final PsiVariable relevantStringVar = context.findRelevantStringInContext(parameter.getName());
        if (relevantStringVar == null) {
          notMatchedStringVars++;
        }
        else {
          parametersMap.put(i, new VariableSubLookupElement(relevantStringVar));
        }
      }
      else if (!ChainCompletionStringUtil.isPrimitiveOrArrayOfPrimitives(typeQName)) {
        final Collection<PsiVariable> contextVariables = context.getVariables(typeQName);
        final PsiVariable contextVariable = ContainerUtil.getFirstItem(contextVariables, null);
        if (contextVariable != null) {
          if (contextVariables.size() == 1) parametersMap.put(i, new VariableSubLookupElement(contextVariable));
          matchedParametersInContext++;
          continue;
        }
        final Collection<ContextRelevantVariableGetter> relevantVariablesGetters = context.getRelevantVariablesGetters(typeQName);
        final ContextRelevantVariableGetter contextVariableGetter = ContainerUtil.getFirstItem(relevantVariablesGetters, null);
        if (contextVariableGetter != null) {
          if (relevantVariablesGetters.size() == 1) parametersMap.put(i, contextVariableGetter.createSubLookupElement());
          matchedParametersInContext++;
          continue;
        }
        final Collection<PsiMethod> containingClassMethods = context.getContainingClassMethods(typeQName);
        final PsiMethod contextRelevantGetter = ContainerUtil.getFirstItem(containingClassMethods, null);
        if (contextRelevantGetter != null) {
          if (containingClassMethods.size() == 1) parametersMap.put(i, new GetterLookupSubLookupElement(method.getName()));
          matchedParametersInContext++;
          continue;
        }
        final ContextRelevantStaticMethod contextRelevantStaticMethod =
          ContainerUtil.getFirstItem(staticMethodSearcher.getRelevantStaticMethods(typeQName, weight), null);
        if (contextRelevantStaticMethod != null) {
          //
          // In most cases it is not really relevant
          //
          //parametersMap.put(i, contextRelevantStaticMethod.createLookupElement());
          matchedParametersInContext++;
          continue;
        }
        if (!nullableNotNullManager.isNullable(parameter, true)) {
          unreachableParametersCount++;
        }
      }
    }
    final LookupElement lookupElement;
    if (isHeadMethod) {
      if (method.hasModifierProperty(PsiModifier.STATIC)) {
        hasCallingVariableInContext = true;
        lookupElement = createLookupElement(method, parametersMap);
      }
      else if (method.isConstructor()) {
        return null;
      }
      else {
        @SuppressWarnings("ConstantConditions")
        final String classQName = qualifierClass.getQualifiedName();
        if (classQName == null) return null;
        final Object e = ContainerUtil.getFirstItem(context.getContextRefElements(classQName), null);
        if (e != null) {
          final LookupElement firstChainElement;
          if (e instanceof PsiVariable) {
            firstChainElement = new VariableLookupItem((PsiVariable)e);
          }
          else if (e instanceof PsiMethod) {
            firstChainElement = createLookupElement((PsiMethod)e, null);
          }
          else if (e instanceof LookupElement) {
            firstChainElement = (LookupElement)e;
          }
          else {
            throw new AssertionError();
          }
          hasCallingVariableInContext = true;
          lookupElement = new JavaChainLookupElement(firstChainElement, createLookupElement(method, parametersMap));
        }
        else {
          lookupElement = createLookupElement(method, parametersMap);
          if (!context.getContainingClassQNames().contains(classQName)) {
            introduceNewVariable = true;
          }
        }
      }
    }
    else {
      lookupElement = createLookupElement(method, parametersMap);
    }
    return new MethodProcResult(lookupElement,
                                unreachableParametersCount,
                                notMatchedStringVars,
                                hasCallingVariableInContext,
                                introduceNewVariable,
                                matchedParametersInContext);
  }

  private static class MethodProcResult {
    private final LookupElement myMethodLookup;
    private final int myUnreachableParametersCount;
    private final int myNotMatchedStringVars;
    private final boolean myHasCallingVariableInContext;
    private final boolean myIntroduceNewVariable;
    private final int myMatchedParametersInContext;

    private MethodProcResult(final LookupElement methodLookup,
                             final int unreachableParametersCount,
                             final int notMatchedStringVars,
                             final boolean hasCallingVariableInContext,
                             final boolean introduceNewVariable,
                             final int matchedParametersInContext) {
      myMethodLookup = methodLookup;
      myUnreachableParametersCount = unreachableParametersCount;
      myNotMatchedStringVars = notMatchedStringVars;
      myHasCallingVariableInContext = hasCallingVariableInContext;
      myIntroduceNewVariable = introduceNewVariable;
      myMatchedParametersInContext = matchedParametersInContext;
    }

    private boolean isIntroduceNewVariable() {
      return myIntroduceNewVariable;
    }

    private boolean hasCallingVariableInContext() {
      return myHasCallingVariableInContext;
    }

    private LookupElement getLookupElement() {
      return myMethodLookup;
    }

    private int getUnreachableParametersCount() {
      return myUnreachableParametersCount;
    }

    private int getNotMatchedStringVars() {
      return myNotMatchedStringVars;
    }

    public int getMatchedParametersInContext() {
      return myMatchedParametersInContext;
    }
  }
}

