/*
 * Copyright 2007 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.plugins.relaxNG.model.resolve;

import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import gnu.trove.THashSet;
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
import org.intellij.plugins.relaxNG.model.*;
import org.intellij.plugins.relaxNG.xml.dom.RngGrammar;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.Map;
import java.util.Set;

/*
* Created by IntelliJ IDEA.
* User: sweinreuter
* Date: 24.08.2007
*/
public class DefinitionResolver extends CommonElement.Visitor implements
        CachedValueProvider<Map<String, Set<Define>>>, Factory<Set<Define>> {

  private static final Key<CachedValue<Map<String, Set<Define>>>> KEY = Key.create("CACHED_DEFINES");

  private static final ThreadLocal<Set<PsiFile>> myVisitedFiles = new ThreadLocal<Set<PsiFile>>();
  private static final ThreadLocal<Map<String, Set<Define>>> myDefines = new ThreadLocal<Map<String, Set<Define>>>() {
    @Override
    protected Map<String, Set<Define>> initialValue() {
      return ContainerUtil.newHashMap();
    }
  };

  private final Grammar myScope;

  private DefinitionResolver(Grammar scope) {
    myScope = scope;
  }

  @Override
  public void visitInclude(Include include) {
    include.acceptChildren(this);

    final PsiFile value = include.getInclude();
    if (myVisitedFiles.get() == null) {
      myVisitedFiles.set(ContainerUtil.<PsiFile>newIdentityTroveSet());
    }
    if (value != null && myVisitedFiles.get().add(value)) {
      doVisitRncOrRngFile(value, this);
    }
  }

  private static void doVisitRncOrRngFile(PsiFile file, CommonElement.Visitor visitor) {
    if (file instanceof RncFile) {
      final Grammar grammar = ((RncFile)file).getGrammar();
      if (grammar != null) {
        grammar.acceptChildren(visitor);
      }
    } else if (file instanceof XmlFile) {
      final DomManager mgr = DomManager.getDomManager(file.getProject());
      final DomFileElement<RngGrammar> element = mgr.getFileElement((XmlFile)file, RngGrammar.class);
      if (element != null) {
        element.getRootElement().acceptChildren(visitor);
      }
    }
  }

  @Override
  public void visitDiv(Div div) {
    div.acceptChildren(this);
  }

  @Override
  public void visitDefine(Define def) {
    ContainerUtil.getOrCreate(myDefines.get(), def.getName(), this).add(def);
  }

  @Override
  public void visitPattern(Pattern pattern) {
  }

  @Override
  public void visitGrammar(Grammar pattern) {
  }

  @Override
  public void visitRef(Ref ref) {
  }


  @Override
  public Set<Define> create() {
    return new THashSet<Define>();
  }

  @Override
  public Result<Map<String, Set<Define>>> compute() {
    try {
      myScope.acceptChildren(this);

      final PsiElement psiElement = myScope.getPsiElement();
      if (psiElement == null || !psiElement.isValid()) {
        return Result.create(null, ModificationTracker.EVER_CHANGED);
      }

      final PsiFile file = psiElement.getContainingFile();
      if (myVisitedFiles.get() != null) {
        myVisitedFiles.get().add(file);
        return Result.create(myDefines.get(), myVisitedFiles.get().toArray());
      } else {
        return Result.create(myDefines.get(), file);
      }
    } finally {
      myVisitedFiles.remove();
      myDefines.remove();
    }
  }

  @Nullable
  public static Set<Define> resolve(Grammar scope, final String value) {
    final Map<String, Set<Define>> map = getAllVariants(scope);
    if (map == null) {
      return null;
    }

    final Set<Define> set = map.get(value);

    // actually we should always do this, but I'm a bit afraid of the performance impact
    if (set == null || set.size() == 0) {
      final PsiElement element = scope.getPsiElement();
      if (element != null) {
        final PsiFile file = element.getContainingFile();
        if (file instanceof XmlFile) {
          final BackwardDefinitionResolver resolver = new BackwardDefinitionResolver(value);
          RelaxIncludeIndex.processBackwardDependencies((XmlFile)file, resolver);
          return resolver.getResult();
        }
      }
    }

    return set;
  }

  @Nullable
  public static Map<String, Set<Define>> getAllVariants(Grammar scope) {
    final PsiElement psiElement = scope.getPsiElement();
    if (psiElement == null || !psiElement.isValid()) return null;

    final CachedValuesManager manager = CachedValuesManager.getManager(psiElement.getProject());
    CachedValue<Map<String, Set<Define>>> data = psiElement.getUserData(KEY);
    if (data == null || !((DefinitionResolver)data.getValueProvider()).isValid()) {
      final DefinitionResolver resolver = new DefinitionResolver(scope);
      data = manager.createCachedValue(resolver, false);
      psiElement.putUserData(KEY, data);
    }
    return data.getValue();
  }

  private boolean isValid() {
    final PsiElement element = myScope.getPsiElement();
    return element != null && element.isValid();
  }

  private static class BackwardDefinitionResolver implements PsiElementProcessor<XmlFile> {
    private final String myValue;
    private Define myResult;
    private final Set<PsiFile> myVisitedPsiFiles = new HashSet<PsiFile>();

    public BackwardDefinitionResolver(String value) {
      myValue = value;
    }

    @Override
    public boolean execute(@NotNull XmlFile element) {
      final Grammar g = GrammarFactory.getGrammar(element);
      if (g != null) {
        g.acceptChildren(new CommonElement.Visitor() {
          @Override
          public void visitElement(CommonElement pattern) {
            if (myResult == null) {
              super.visitElement(pattern);
            }
          }

          @Override
          public void visitDefine(Define define) {
            if (myValue.equals(define.getName())) {
              myResult = define;
            }
          }

          @Override
          public void visitInclude(Include include) {
            final PsiFile file = include.getInclude();
            if (file != null && myVisitedPsiFiles.add(file)) {
              doVisitRncOrRngFile(file, this);
            }
          }
        });
      }
      return myResult == null;
    }

    @Nullable
    public Set<Define> getResult() {
      return myResult != null ? Collections.singleton(myResult) : null;
    }
  }
}