/*
 * 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.
 */

/*
 * Class LineBreakpoint
 * @author Jeka
 */
package com.intellij.debugger.ui.breakpoints;

import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.actions.ThreadDumpAction;
import com.intellij.debugger.engine.ContextUtil;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex;
import com.intellij.psi.jsp.JspFile;
import com.intellij.psi.search.EverythingGlobalScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.*;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.request.BreakpointRequest;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class LineBreakpoint extends BreakpointWithHighlighter {
  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.LineBreakpoint");

  @Nullable
  private String myOwnerMethodName;
  public static final @NonNls Key<LineBreakpoint> CATEGORY = BreakpointCategory.lookup("line_breakpoints");

  protected LineBreakpoint(Project project, XBreakpoint xBreakpoint) {
    super(project, xBreakpoint);
  }

  @Override
  protected Icon getDisabledIcon(boolean isMuted) {
    final Breakpoint master = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().findMasterBreakpoint(this);
    if (isMuted) {
      return master == null? AllIcons.Debugger.Db_muted_disabled_breakpoint : AllIcons.Debugger.Db_muted_dep_line_breakpoint;
    }
    else {
      return master == null? AllIcons.Debugger.Db_disabled_breakpoint : AllIcons.Debugger.Db_dep_line_breakpoint;
    }
  }

  @Override
  protected Icon getSetIcon(boolean isMuted) {
    if (isRemoveAfterHit()) {
      return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
    }
    return isMuted? AllIcons.Debugger.Db_muted_breakpoint : AllIcons.Debugger.Db_set_breakpoint;
  }

  @Override
  protected Icon getInvalidIcon(boolean isMuted) {
    return isMuted? AllIcons.Debugger.Db_muted_invalid_breakpoint : AllIcons.Debugger.Db_invalid_breakpoint;
  }

  @Override
  protected Icon getVerifiedIcon(boolean isMuted) {
    if (isRemoveAfterHit()) {
      return isMuted ? AllIcons.Debugger.Db_muted_temporary_breakpoint : AllIcons.Debugger.Db_temporary_breakpoint;
    }
    return isMuted? AllIcons.Debugger.Db_muted_verified_breakpoint : AllIcons.Debugger.Db_verified_breakpoint;
  }

  @Override
  protected Icon getVerifiedWarningsIcon(boolean isMuted) {
    return isMuted? AllIcons.Debugger.Db_muted_verified_warning_breakpoint : AllIcons.Debugger.Db_verified_warning_breakpoint;
  }

  @Override
  public Key<LineBreakpoint> getCategory() {
    return CATEGORY;
  }

  @Override
  protected void reload(PsiFile file) {
    super.reload(file);
    XSourcePosition position = myXBreakpoint.getSourcePosition();
    if (position != null) {
      int offset = position.getOffset();
      myOwnerMethodName = findOwnerMethod(file, offset);
    }
  }

  @Override
  protected void createOrWaitPrepare(DebugProcessImpl debugProcess, String classToBeLoaded) {
    if (isInScopeOf(debugProcess, classToBeLoaded)) {
      super.createOrWaitPrepare(debugProcess, classToBeLoaded);
    }
  }

  @Override
  protected void createRequestForPreparedClass(final DebugProcessImpl debugProcess, final ReferenceType classType) {
    if (!isInScopeOf(debugProcess, classType.name())) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(classType.name() + " is out of debug-process scope, breakpoint request won't be created for line " + getLineIndex());
      }
      return;
    }
    try {
      List<Location> locations = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
      if (!locations.isEmpty()) {
        for (Location loc : locations) {
          if (LOG.isDebugEnabled()) {
            LOG.debug("Found location [codeIndex=" + loc.codeIndex() +"] for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && loc.method().isObsolete()));
          }
          if (!acceptLocation(debugProcess, classType, loc)) {
            continue;
          }
          final BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(this, loc);
          debugProcess.getRequestsManager().enableRequest(request);
          if (LOG.isDebugEnabled()) {
            LOG.debug("Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex() + "; codeIndex=" + loc.codeIndex());
          }
        }
      }
      else {
        // there's no executable code in this class
        debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message(
          "error.invalid.breakpoint.no.executable.code", (getLineIndex() + 1), classType.name())
        );
        if (LOG.isDebugEnabled()) {
          LOG.debug("No locations of type " + classType.name() + " found at line " + getLineIndex());
        }
      }
    }
    catch (ClassNotPreparedException ex) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("ClassNotPreparedException: " + ex.getMessage());
      }
      // there's a chance to add a breakpoint when the class is prepared
    }
    catch (ObjectCollectedException ex) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("ObjectCollectedException: " + ex.getMessage());
      }
      // there's a chance to add a breakpoint when the class is prepared
    }
    catch (InvalidLineNumberException ex) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("InvalidLineNumberException: " + ex.getMessage());
      }
      debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
    }
    catch (InternalException ex) {
      LOG.info(ex);
    }
    catch(Exception ex) {
      LOG.info(ex);
    }
    updateUI();
  }

  protected boolean acceptLocation(DebugProcessImpl debugProcess, ReferenceType classType, Location loc) {
    return true;
  }

  private boolean isInScopeOf(DebugProcessImpl debugProcess, String className) {
    final SourcePosition position = getSourcePosition();
    if (position != null) {
      final VirtualFile breakpointFile = position.getFile().getVirtualFile();
      final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
      if (breakpointFile != null && fileIndex.isUnderSourceRootOfType(breakpointFile, JavaModuleSourceRootTypes.SOURCES)) {
        // apply filtering to breakpoints from content sources only, not for sources attached to libraries
        final Collection<VirtualFile> candidates = findClassCandidatesInSourceContent(className, debugProcess.getSearchScope(), fileIndex);
        if (LOG.isDebugEnabled()) {
          LOG.debug("Found "+ (candidates == null? "null" : candidates.size()) + " candidate containing files for class " + className);
        }
        if (candidates == null) {
          return true;
        }
        for (VirtualFile classFile : candidates) {
          if (LOG.isDebugEnabled()) {
            LOG.debug("Breakpoint file: " + breakpointFile.getPath()+ "; candidate file: " + classFile.getPath());
          }
          if (breakpointFile.equals(classFile)) {
            return true;
          }
        }
        if (LOG.isDebugEnabled()) {
          final GlobalSearchScope scope = debugProcess.getSearchScope();
          final boolean contains = scope.contains(breakpointFile);
          final Project project = getProject();
          final List<VirtualFile> files = ContainerUtil.map(
            JavaFullClassNameIndex.getInstance().get(className.hashCode(), project, scope), new Function<PsiClass, VirtualFile>() {
            @Override
            public VirtualFile fun(PsiClass aClass) {
              return aClass.getContainingFile().getVirtualFile();
            }
          });
          final List<VirtualFile> allFiles = ContainerUtil.map(
            JavaFullClassNameIndex.getInstance().get(className.hashCode(), project, new EverythingGlobalScope(project)), new Function<PsiClass, VirtualFile>() {
            @Override
            public VirtualFile fun(PsiClass aClass) {
              return aClass.getContainingFile().getVirtualFile();
            }
          });
          final VirtualFile contentRoot = fileIndex.getContentRootForFile(breakpointFile);
          final Module module = fileIndex.getModuleForFile(breakpointFile);

          LOG.debug("Did not find '" +
                    className + "' in " + scope +
                    "; contains=" + contains +
                    "; contentRoot=" + contentRoot +
                    "; module = " + module +
                    "; all files in index are: " + files+
                    "; all possible files are: " + allFiles
          );
        }
        
        return false;
      }
    }
    return true;
  }

  @Nullable
  private Collection<VirtualFile> findClassCandidatesInSourceContent(final String className, final GlobalSearchScope scope, final ProjectFileIndex fileIndex) {
    final int dollarIndex = className.indexOf("$");
    final String topLevelClassName = dollarIndex >= 0? className.substring(0, dollarIndex) : className;
    return ApplicationManager.getApplication().runReadAction(new Computable<Collection<VirtualFile>>() {
      @Override
      @Nullable
      public Collection<VirtualFile> compute() {
        final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(topLevelClassName, scope);
        if (LOG.isDebugEnabled()) {
          LOG.debug("Found "+ classes.length + " classes " + topLevelClassName + " in scope "+scope);
        }
        if (classes.length == 0) {
          return null;
        }
        final List<VirtualFile> list = new ArrayList<VirtualFile>(classes.length);
        for (PsiClass aClass : classes) {
          final PsiFile psiFile = aClass.getContainingFile();
          
          if (LOG.isDebugEnabled()) {
            final StringBuilder msg = new StringBuilder();
            msg.append("Checking class ").append(aClass.getQualifiedName());
            msg.append("\n\t").append("PsiFile=").append(psiFile);
            if (psiFile != null) {
              final VirtualFile vFile = psiFile.getVirtualFile();
              msg.append("\n\t").append("VirtualFile=").append(vFile);
              if (vFile != null) {
                msg.append("\n\t").append("isInSourceContent=").append(fileIndex.isUnderSourceRootOfType(vFile, JavaModuleSourceRootTypes.SOURCES));
              }
            }
            LOG.debug(msg.toString());
          }
          
          if (psiFile == null) {
            return null;
          }
          final VirtualFile vFile = psiFile.getVirtualFile();
          if (vFile == null || !fileIndex.isUnderSourceRootOfType(vFile, JavaModuleSourceRootTypes.SOURCES)) {
            return null; // this will switch off the check if at least one class is from libraries
          }
          list.add(vFile);
        }
        return list;
      }
    });
  }

  @Override
  protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
    String className = null;
    final ObjectReference thisObject = (ObjectReference)context.getThisObject();
    if (thisObject != null) {
      className = thisObject.referenceType().name();
    }
    else {
      final StackFrameProxyImpl frame = context.getFrameProxy();
      if (frame != null) {
        className = frame.location().declaringType().name();
      }
    }
    return className;
  }

  public String toString() {
    return getDescription();
  }

  @Override
  public String getShortName() {
    return getDisplayInfoInternal(false, 30);
  }

  @Override
  public String getDisplayName() {
    return getDisplayInfoInternal(true, -1);
  }

  private String getDisplayInfoInternal(boolean showPackageInfo, int totalTextLength) {
    if(isValid()) {
      final int lineNumber = myXBreakpoint.getSourcePosition().getLine() + 1;
      String className = getClassName();
      final boolean hasClassInfo = className != null && className.length() > 0;
      final String methodName = getMethodName();
      final String displayName = methodName != null? methodName + "()" : null;
      final boolean hasMethodInfo = displayName != null && displayName.length() > 0;
      if (hasClassInfo || hasMethodInfo) {
        final StringBuilder info = StringBuilderSpinAllocator.alloc();
        try {
          boolean isFile = myXBreakpoint.getSourcePosition().getFile().getName().equals(className);
          String packageName = null;
          if (hasClassInfo) {
            final int dotIndex = className.lastIndexOf(".");
            if (dotIndex >= 0 && !isFile) {
              packageName = className.substring(0, dotIndex);
              className = className.substring(dotIndex + 1); 
            }

            if (totalTextLength != -1) {
              if (className.length() + (hasMethodInfo ? displayName.length() : 0) > totalTextLength + 3) {
                int offset = totalTextLength - (hasMethodInfo ? displayName.length() : 0);
                if (offset > 0 && offset < className.length()) {
                  className = className.substring(className.length() - offset);
                  info.append("...");
                }
              }
            }
            
            info.append(className);
          }
          if(hasMethodInfo) {
            if (isFile) {
              info.append(":");
            }
            else if (hasClassInfo) {
              info.append(".");
            }
            info.append(displayName);
          }
          if (showPackageInfo && packageName != null) {
            info.append(" (").append(packageName).append(")");
          }
          return DebuggerBundle.message("line.breakpoint.display.name.with.class.or.method", lineNumber, info.toString());
        }
        finally {
          StringBuilderSpinAllocator.dispose(info);
        }
      }
      return DebuggerBundle.message("line.breakpoint.display.name", lineNumber);
    }
    return DebuggerBundle.message("status.breakpoint.invalid");
  }

  @Nullable
  private static String findOwnerMethod(final PsiFile file, final int offset) {
    if (offset < 0 || file instanceof JspFile) {
      return null;
    }
    if (file instanceof PsiClassOwner) {
      return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
        @Override
        public String compute() {
          final PsiMethod method = DebuggerUtilsEx.findPsiMethod(file, offset);
          return method != null? method.getName() : null;
        }
      });
    }
    return null;
  }

  @Override
  public String getEventMessage(LocatableEvent event) {
    final Location location = event.location();
    String sourceName;
    try {
      sourceName = location.sourceName();
    }
    catch (AbsentInformationException e) {
      sourceName = getFileName();
    }

    final boolean printFullTrace = Registry.is("debugger.breakpoint.message.full.trace");

    StringBuilder builder = new StringBuilder();
    if (printFullTrace) {
      builder.append(DebuggerBundle.message(
        "status.line.breakpoint.reached.full.trace",
        location.declaringType().name() + "." + location.method().name())
      );
      try {
        final List<StackFrame> frames = event.thread().frames();
        renderTrace(frames, builder);
      }
      catch (IncompatibleThreadStateException e) {
        builder.append("Stacktrace not available: ").append(e.getMessage());
      }
    }
    else {
      builder.append(DebuggerBundle.message(
        "status.line.breakpoint.reached",
        location.declaringType().name() + "." + location.method().name(),
        sourceName,
        getLineIndex() + 1
      ));
    }
    return builder.toString();
  }

  private static void renderTrace(List<StackFrame> frames, StringBuilder buffer) {
    for (final StackFrame stackFrame : frames) {
      final Location location = stackFrame.location();
      buffer.append("\n\t  ").append(ThreadDumpAction.renderLocation(location));
    }
  }

  @Override
  public PsiElement getEvaluationElement() {
    return ContextUtil.getContextElement(getSourcePosition());
  }

  public static LineBreakpoint create(@NotNull Project project, XBreakpoint xBreakpoint) {
    LineBreakpoint breakpoint = new LineBreakpoint(project, xBreakpoint);
    return (LineBreakpoint)breakpoint.init();
  }

  //@Override
  //public boolean canMoveTo(SourcePosition position) {
  //  if (!super.canMoveTo(position)) {
  //    return false;
  //  }
  //  final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(position.getFile());
  //  return canAddLineBreakpoint(myProject, document, position.getLine());
  //}

  public static boolean canAddLineBreakpoint(Project project, final Document document, final int lineIndex) {
    if (lineIndex < 0 || lineIndex >= document.getLineCount()) {
      return false;
    }
    final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
    final LineBreakpoint breakpointAtLine = breakpointManager.findBreakpoint( document, document.getLineStartOffset(lineIndex), CATEGORY);
    if (breakpointAtLine != null) {
      // there already exists a line breakpoint at this line
      return false;
    }
    PsiDocumentManager.getInstance(project).commitDocument(document);

    final boolean[] canAdd = new boolean[]{false};
    XDebuggerUtil.getInstance().iterateLine(project, document, lineIndex, new Processor<PsiElement>() {
      @Override
      public boolean process(PsiElement element) {
        if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
          return true;
        }
        PsiElement child = element;
        while(element != null) {

          final int offset = element.getTextOffset();
          if (offset >= 0) {
            if (document.getLineNumber(offset) != lineIndex) {
              break;
            }
          }
          child = element;
          element = element.getParent();
        }

        if(child instanceof PsiMethod && child.getTextRange().getEndOffset() >= document.getLineEndOffset(lineIndex)) {
          PsiCodeBlock body = ((PsiMethod)child).getBody();
          if(body == null) {
            canAdd[0] = false;
          }
          else {
            PsiStatement[] statements = body.getStatements();
            canAdd[0] = statements.length > 0 && document.getLineNumber(statements[0].getTextOffset()) == lineIndex;
          }
        }
        else {
          canAdd[0] = true;
        }
        return false;
      }
    });

    return canAdd[0];
  }

  @Nullable
  public String getMethodName() {
    return myOwnerMethodName;
  }

}
