/*
 * 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.jetbrains.python.templateLanguages;

import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceHelper;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileSystemItemUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.psi.WeakFileReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
 * @author yole
 */
public class TemplateFileReference extends WeakFileReference {
  public TemplateFileReference(@NotNull FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
    super(fileReferenceSet, range, index, text);
  }

  @Nullable
  @Override
  public String getUnresolvedDescription() {
    return "Template file '" + getCanonicalText() + "' not found";
  }

  @Override
  public PsiElement bindToElement(@NotNull PsiElement element, boolean absolute) throws IncorrectOperationException {
    if (!(element instanceof PsiFileSystemItem)) {
      throw new IncorrectOperationException("Cannot bind to element, should be instanceof PsiFileSystemItem: " + element);
    }

    final PsiFileSystemItem fileSystemItem = (PsiFileSystemItem)element;
    VirtualFile dstVFile = fileSystemItem.getVirtualFile();
    if (dstVFile == null) throw new IncorrectOperationException("Cannot bind to non-physical element:" + element);

    PsiFile file = getElement().getContainingFile();
    PsiElement contextPsiFile = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
    if (contextPsiFile != null) file = contextPsiFile.getContainingFile(); // use host file!
    final VirtualFile curVFile = file.getVirtualFile();
    if (curVFile == null) throw new IncorrectOperationException("Cannot bind from non-physical element:" + file);

    String newName;

    PsiFileSystemItem curItem = null;
    PsiFileSystemItem dstItem = null;

    PsiFileSystemItem _dstItem = FileReferenceHelper.getPsiFileSystemItem(file.getManager(), dstVFile);
    PsiFileSystemItem _curItem = FileReferenceHelper.getPsiFileSystemItem(file.getManager(), curVFile);
    if (_dstItem != null && _curItem != null) {
      curItem = _curItem;
      dstItem = _dstItem;
    }

    final Collection<PsiFileSystemItem> contexts = getContexts();
    switch (contexts.size()) {
      case 0:
        break;
      default:
        for (PsiFileSystemItem context : contexts) {
          final VirtualFile contextFile = context.getVirtualFile();
          assert contextFile != null;
          if (VfsUtil.isAncestor(contextFile, dstVFile, true)) {
            final String path = VfsUtilCore.getRelativePath(dstVFile, contextFile, '/');
            if (path != null) {
              return rename(path.replace("/", getFileReferenceSet().getSeparatorString()));
            }
          }
        }
    }
    if (curItem == null) {
      throw new IncorrectOperationException("Cannot find path between files; " +
                                            "src = " + curVFile.getPresentableUrl() + "; " +
                                            "dst = " + dstVFile.getPresentableUrl() + "; " +
                                            "Contexts: " + contexts);
    }
    if (curItem.equals(dstItem)) {
      if (getCanonicalText().equals(dstItem.getName())) {
        return getElement();
      }
      return ElementManipulators.getManipulator(getElement()).handleContentChange(getElement(), getRangeInElement(), file.getName());
    }
    newName = PsiFileSystemItemUtil.getRelativePath(curItem, dstItem);
    if (newName == null) {
      return getElement();
    }

    return rename(newName);
  }
}
