/*
 * Copyright 2000-2009 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.
 */

/*
 * Interface DebuggerContextImpl
 * @author Jeka
 */
package com.intellij.debugger.impl;

import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.ContextUtil;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jetbrains.annotations.Nullable;


public final class DebuggerContextImpl implements DebuggerContext {
  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerContextImpl");

  public static final DebuggerContextImpl EMPTY_CONTEXT = createDebuggerContext((DebuggerSession)null, null, null, null);

  private boolean myInitialized;

  @Nullable
  private final DebuggerSession myDebuggerSession;
  private final DebugProcessImpl myDebugProcess;
  private final SuspendContextImpl mySuspendContext;
  private final ThreadReferenceProxyImpl myThreadProxy;

  private StackFrameProxyImpl myFrameProxy;
  private SourcePosition mySourcePosition;
  private PsiElement myContextElement;

  private DebuggerContextImpl(@Nullable DebuggerSession session,
                              @Nullable DebugProcessImpl debugProcess,
                              @Nullable SuspendContextImpl context,
                              ThreadReferenceProxyImpl threadProxy,
                              StackFrameProxyImpl frameProxy,
                              SourcePosition position,
                              PsiElement contextElement,
                              boolean initialized) {
    LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy());
    LOG.assertTrue(debugProcess != null || frameProxy == null && threadProxy == null);
    myDebuggerSession = session;
    myThreadProxy = threadProxy;
    myFrameProxy = frameProxy;
    myDebugProcess = debugProcess;
    mySourcePosition = position;
    mySuspendContext = context;
    myContextElement = contextElement;
    myInitialized = initialized;
  }

  @Nullable
  public DebuggerSession getDebuggerSession() {
    return myDebuggerSession;
  }

  @Nullable
  @Override
  public DebugProcessImpl getDebugProcess() {
    return myDebugProcess;
  }

  public ThreadReferenceProxyImpl getThreadProxy() {
    return myThreadProxy;
  }

  @Override
  public SuspendContextImpl getSuspendContext() {
    return mySuspendContext;
  }

  @Override
  public Project getProject() {
    return myDebugProcess != null ? myDebugProcess.getProject() : null;
  }

  @Override
  @Nullable
  public StackFrameProxyImpl getFrameProxy() {
    LOG.assertTrue(myInitialized);
    return myFrameProxy;
  }

  public SourcePosition getSourcePosition() {
    LOG.assertTrue(myInitialized);
    return mySourcePosition;
  }

  public PsiElement getContextElement() {
    LOG.assertTrue(myInitialized);
    PsiElement contextElement = myContextElement;
    if(contextElement != null && !contextElement.isValid()) {
      myContextElement = ContextUtil.getContextElement(mySourcePosition);
    }
    return myContextElement;
  }

  public EvaluationContextImpl createEvaluationContext(Value thisObject) {
    DebuggerManagerThreadImpl.assertIsManagerThread();
    return new EvaluationContextImpl(getSuspendContext(), getFrameProxy(), thisObject);
  }

  @Nullable
  public EvaluationContextImpl createEvaluationContext() {
    DebuggerManagerThreadImpl.assertIsManagerThread();
    StackFrameProxyImpl frameProxy = getFrameProxy();
    ObjectReference objectReference;
    try {
      objectReference = frameProxy != null ? frameProxy.thisObject() : null;
    }
    catch (EvaluateException e) {
      LOG.info(e);
      objectReference = null;
    }
    SuspendContextImpl context = getSuspendContext();
    return context != null ? new EvaluationContextImpl(context, frameProxy, objectReference) : null;
  }

  public static DebuggerContextImpl createDebuggerContext(@Nullable DebuggerSession session,
                                                          @Nullable SuspendContextImpl context,
                                                          ThreadReferenceProxyImpl threadProxy,
                                                          StackFrameProxyImpl frameProxy) {
    LOG.assertTrue(frameProxy == null || threadProxy == null || threadProxy == frameProxy.threadProxy());
    LOG.assertTrue(session == null || session.getProcess() != null);
    return new DebuggerContextImpl(session, session != null ? session.getProcess() : null, context, threadProxy, frameProxy, null, null, context == null);
  }

  public void initCaches() {
    if(myInitialized) return;

    myInitialized = true;
    if(myFrameProxy == null) {
      if(myThreadProxy != null) {
        try {
          myFrameProxy = myThreadProxy.frameCount() > 0 ? myThreadProxy.frame(0) : null;
        }
        catch (EvaluateException ignored) {
        }
      }
    }

    if (myFrameProxy != null) {
      PsiDocumentManager.getInstance(getProject()).commitAndRunReadAction(new Runnable() {
        @Override
        public void run() {
          if (mySourcePosition == null) {
            mySourcePosition = ContextUtil.getSourcePosition(DebuggerContextImpl.this);
          }
          myContextElement = ContextUtil.getContextElement(mySourcePosition);
        }
      });
    }
  }

  public void setPositionCache(SourcePosition position) {
    //LOG.assertTrue(!myInitialized, "Debugger context is initialized. Cannot change caches");
    mySourcePosition = position;
  }

  public boolean isInitialised() {
    return myInitialized;
  }

  public boolean isEvaluationPossible() {
    final DebugProcessImpl debugProcess = getDebugProcess();
    return debugProcess != null && debugProcess.getSuspendManager().getPausedContext() != null;
  }
}