/*
 * 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 org.jetbrains.plugins.groovy.lang.resolve;

import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.PairProcessor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
import org.jetbrains.plugins.groovy.lang.resolve.processors.GrScopeProcessorWithHints;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.ConcurrentMap;

/**
* @author peter
*/
class DeclarationCacheKey {
  private static final CachedValueProvider<ConcurrentMap<DeclarationCacheKey, List<DeclarationHolder>>> VALUE_PROVIDER =
    new CachedValueProvider<ConcurrentMap<DeclarationCacheKey, List<DeclarationHolder>>>() {
      @Nullable
      @Override
      public Result<ConcurrentMap<DeclarationCacheKey, List<DeclarationHolder>>> compute() {
        ConcurrentMap<DeclarationCacheKey, List<DeclarationHolder>> map = ContainerUtil.newConcurrentMap();
        return Result.create(map, PsiModificationTracker.MODIFICATION_COUNT);
      }
    };
  @Nullable private final String name;
  @NotNull private final EnumSet<ClassHint.ResolveKind> kinds;
  private final boolean nonCode;
  @NotNull private final PsiElement place;

  DeclarationCacheKey(@Nullable String name, ClassHint hint, boolean nonCode, @NotNull PsiElement place) {
    this.name = name;
    this.kinds = getResolveKinds(hint);
    this.nonCode = nonCode;
    this.place = place;
  }

  private static EnumSet<ClassHint.ResolveKind> getResolveKinds(ClassHint hint) {
    EnumSet<ClassHint.ResolveKind> set = EnumSet.noneOf(ClassHint.ResolveKind.class);
    for (ClassHint.ResolveKind kind : ClassHint.ResolveKind.values()) {
      if (hint.shouldProcess(kind)) {
        set.add(kind);
      }
    }
    return set;
  }


  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof DeclarationCacheKey)) {
      return false;
    }

    DeclarationCacheKey key = (DeclarationCacheKey)o;

    if (nonCode != key.nonCode) {
      return false;
    }
    if (!kinds.equals(key.kinds)) {
      return false;
    }
    if (name != null ? !name.equals(key.name) : key.name != null) {
      return false;
    }

    if (place != key.place) return false;

    return true;
  }

  @Override
  public int hashCode() {
    int result = name != null ? name.hashCode() : 0;
    result = 31 * result + kinds.hashCode();
    result = 31 * result + (nonCode ? 1 : 0);
    result = 31* result + place.hashCode();
    return result;
  }

  @Override
  public String toString() {
    return "DeclarationCacheKey{" +
           "name='" + name + '\'' +
           ", kinds=" + kinds +
           ", nonCode=" + nonCode +
           ", place=" + place.toString() +
           '}';
  }

  private List<DeclarationHolder> collectDeclarations(final PsiElement place) {
    final ArrayList<DeclarationHolder> result = new ArrayList<DeclarationHolder>();
    PsiTreeUtil.treeWalkUp(place, null, new PairProcessor<PsiElement, PsiElement>() {
      @Override
      public boolean process(PsiElement scope, PsiElement lastParent) {
        result.add(collectScopeDeclarations(scope, lastParent));
        if (nonCode && scope instanceof GrClosableBlock) return false; //closures tree walk up themselves if non code declarataions are acepted
        return true;
      }
    });
    return result;
  }

  private DeclarationHolder collectScopeDeclarations(PsiElement scope, PsiElement lastParent) {
    MyCollectProcessor plainCollector = new MyCollectProcessor();
    MyCollectProcessor nonCodeCollector = new MyCollectProcessor();
    ResolveUtil.doProcessDeclarations(place, lastParent, scope, plainCollector, nonCode ? nonCodeCollector : null, ResolveState.initial());
    return new DeclarationHolder(scope, plainCollector.declarations, nonCodeCollector.declarations);
  }

  private List<DeclarationHolder> getAllDeclarations(PsiElement place) {
    ConcurrentMap<DeclarationCacheKey, List<DeclarationHolder>> cache = CachedValuesManager.getCachedValue(place, VALUE_PROVIDER);
    List<DeclarationHolder> declarations = cache.get(this);
    if (declarations == null) {
      declarations = collectDeclarations(place);
      cache.putIfAbsent(this, declarations);
    }
    return declarations;
  }

  boolean processCachedDeclarations(PsiElement place, PsiScopeProcessor processor) {
    for (DeclarationHolder holder : getAllDeclarations(place)) {
      ProgressManager.checkCanceled();
      if (!holder.processCachedDeclarations(processor)) {
        return false;
      }
    }
    return true;
  }

  private static class DeclarationHolder {
    final PsiElement scope;
    final List<Pair<PsiElement, ResolveState>> plainDeclarations;
    final List<Pair<PsiElement, ResolveState>> nonCodeDeclarations;

    private DeclarationHolder(PsiElement scope,
                              List<Pair<PsiElement, ResolveState>> plainDeclarations,
                              List<Pair<PsiElement, ResolveState>> nonCodeDeclarations) {
      this.scope = scope;
      this.plainDeclarations = plainDeclarations;
      this.nonCodeDeclarations = nonCodeDeclarations;
    }

    boolean processCachedDeclarations(PsiScopeProcessor processor) {
      PsiScopeProcessor realProcessor = ResolveUtil.substituteProcessor(processor, scope);
      for (Pair<PsiElement, ResolveState> pair : plainDeclarations) {
        if (!realProcessor.execute(pair.first, pair.second)) {
          return false;
        }
      }
      for (Pair<PsiElement, ResolveState> pair : nonCodeDeclarations) {
        if (!processor.execute(pair.first, pair.second)) {
          return false;
        }
      }

      ResolveUtil.issueLevelChangeEvents(processor, scope);
      return true;
    }

    @Override
    public String toString() {
      return "[scope=" + scope.toString() + ", plain=" + plainDeclarations.size() + ", nonCode=" + nonCodeDeclarations.size();
    }
  }

  private class MyCollectProcessor extends GrScopeProcessorWithHints {
    final List<Pair<PsiElement, ResolveState>> declarations = ContainerUtil.newArrayList();

    public MyCollectProcessor() {
      super(DeclarationCacheKey.this.name, DeclarationCacheKey.this.kinds);
    }

    @Override
    public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) {
      declarations.add(Pair.create(element, state));
      return true;
    }
  }
}

