package com.intellij.dupLocator.util;

import com.intellij.dupLocator.DuplicatesProfile;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiAnchor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usageView.UsageInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: db
 * Date: Mar 26, 2004
 * Time: 4:58:00 PM
 * To change this template use File | Settings | File Templates.
 */
public abstract class PsiFragment {
  private static final Logger LOG = Logger.getInstance("#com.intellij.dupLocator.PsiFragment");

  protected final PsiAnchor[] myElementAnchors;
  private final Language myLanguage;
  private PsiFragment[] myParents;
  private boolean myDuplicate;
  private boolean myChecked;
  private boolean myNested;
  private int myCost;

  public PsiFragment(PsiElement element) {
    this(element, 0);
  }

  public PsiFragment(PsiElement element, int cost) {
    myElementAnchors = new PsiAnchor[]{createAnchor(element)};
    myDuplicate = false;
    myChecked = false;
    myNested = false;
    myParents = null;
    myCost = cost;
    myLanguage = calcLanguage(element);
  }

  protected Language calcLanguage(PsiElement element) {
    return doGetLanguageForElement(element);
  }

  protected PsiAnchor createAnchor(final PsiElement element) {
    return ApplicationManager.getApplication().runReadAction(new Computable<PsiAnchor>() {
      public PsiAnchor compute() {
        return PsiAnchor.create(element);
      }
    });
  }

  public PsiFragment(List<? extends PsiElement> elements) {
    this(elements, 0, elements.size() - 1);
  }

  public PsiFragment(List<? extends PsiElement> elements, int from, int to) {
    myElementAnchors = new PsiAnchor[to - from + 1];

    for (int i = from; i <= to; i++) {
      myElementAnchors[i - from] = createAnchor(elements.get(i));
    }

    myDuplicate = false;
    myChecked = false;
    myNested = false;
    myParents = null;
    myLanguage = to >= from && from < elements.size()
                 ? calcLanguage(elements.get(from))
                 : null;
  }

  @NotNull
  private static Language doGetLanguageForElement(@NotNull PsiElement element) {
    final DuplicatesProfile profile = DuplicatesProfile.findProfileForLanguage(element.getLanguage());
    if (profile == null) {
      return element.getLanguage();
    }
    return profile.getLanguage(element);
  }

  public void setCost(int c) {
    if (myCost != -1) {
      myCost = c;
    }
  }

  public void markDuplicate() {
    myDuplicate = true;
  }

  public boolean isNested() {
    if (myChecked) {
      return myNested;
    }

    myChecked = true;

    if (myParents != null) {
      PsiFragment parent1 = myParents[0];
      PsiFragment parent2 = myParents[1];

      if (parent1 != null) {
        myNested |= parent1.myDuplicate || parent1.isNested();
        if (parent2 != null) {
          myNested |= parent2.myDuplicate || parent2.isNested();
        }
      }
    }

    return myNested;
  }

  public void setParent(PsiFragment f) {
    if (f == null) return;
    if (myParents == null) {
      myParents = new PsiFragment[]{f, null};
    }
    else {
      if (myParents[0] == f || myParents[1] == f) return;
      if (myParents[1] != null) {
        LOG.error("Third parent set.");
      }

      myParents[1] = f;
    }
  }

  public PsiElement[] getElements() {
    PsiElement[] elements = new PsiElement[myElementAnchors.length];

    for (int i = 0; i < elements.length; i++) {
      elements[i] = myElementAnchors[i].retrieve();
    }

    return elements;
  }

  @Nullable
  public PsiFile getFile() {
    return myElementAnchors.length > 0 ? myElementAnchors[0].getFile() : null;
  }

  public int getStartOffset() {
    return myElementAnchors.length > 0 ? myElementAnchors[0].getStartOffset() : -1;
  }

  public int getEndOffset() {
    return myElementAnchors.length > 0 ? myElementAnchors[myElementAnchors.length - 1].getEndOffset() : -1;
  }

  public boolean intersectsWith(PsiFragment f) {
    final int start = getStartOffset();
    final int end = getEndOffset();
    final int fStart = f.getStartOffset();
    final int fEnd = f.getEndOffset();

    return
      Comparing.equal(f.getFile(), getFile()) && ((start <= fStart && fStart <= end) || (start <= fEnd && fEnd <= end));
  }

  public abstract boolean isEqual(PsiElement[] elements, int discardCost);

  @Nullable
  public UsageInfo getUsageInfo() {
    if (myElementAnchors.length == 1) {
      final PsiElement element = myElementAnchors[0].retrieve();
      if (element == null || !element.isValid()) return null;
      return new UsageInfo(element);
    }

    PsiElement parent = PsiTreeUtil.findCommonParent(getElements());
    if (parent == null) return null;
    int offs = parent.getTextRange().getStartOffset();

    final int startOffsetInParent = getStartOffset() - offs;
    final int endOffsetInParent = getEndOffset() - offs;
    if (startOffsetInParent < 0) return null;
    if (endOffsetInParent < startOffsetInParent) return null;
    return new UsageInfo(parent, startOffsetInParent, endOffsetInParent);
  }

  //debug only
  public String toString() {
    StringBuilder buffer = new StringBuilder();

    for (PsiAnchor psiAnchor : myElementAnchors) {
      final PsiElement element = psiAnchor.retrieve();
      if (element != null) {
        buffer.append(element.getText());
        buffer.append("\n");
      }
    }

    return buffer.toString();
  }

  public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof PsiFragment)) return false;

    PsiFragment other = ((PsiFragment)o);

    return other.getStartOffset() == getStartOffset() &&
           other.getEndOffset() == getEndOffset() &&
           Comparing.equal(other.getFile(), getFile());
  }

  public int hashCode() {
    int result = getStartOffset();
    result += 31 * result + getEndOffset();
    final PsiFile file = getFile();
    if (file != null) {
      result += 31 * result + file.getName().hashCode();
    }
    return result;
  }

  public int getCost() {
    return myCost;
  }

  public int[][] getOffsets() {
    final int[][] result = new int[myElementAnchors.length][2];
    int idx = 0;
    for (PsiAnchor anchor : myElementAnchors) {
      result[idx][0] = anchor.getStartOffset();
      result[idx++][1] = anchor.getEndOffset();
    }
    return result;
  }

  public boolean containsMultipleFragments() {
    return myElementAnchors.length > 1;
  }

  @Nullable
  public Language getLanguage() {
    return myLanguage;
  }
}


