/*
 * Copyright 2000-2014 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.intellij.debugger.engine.evaluation;

import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.JavaRecursiveElementVisitor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Eugene Zhuravlev
 *         Date: Aug 30, 2010
 */
public class CodeFragmentFactoryContextWrapper extends CodeFragmentFactory {
  public static final Key<Value> LABEL_VARIABLE_VALUE_KEY = Key.create("_label_variable_value_key_");
  public static final String DEBUG_LABEL_SUFFIX = "_DebugLabel";

  private final CodeFragmentFactory myDelegate;

  public CodeFragmentFactoryContextWrapper(CodeFragmentFactory delegate) {
    myDelegate = delegate;
  }

  public JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project) {
    return myDelegate.createCodeFragment(item, wrapContext(project, context), project);
  }

  public JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project) {
    return myDelegate.createPresentationCodeFragment(item, wrapContext(project, context), project);
  }

  public boolean isContextAccepted(PsiElement contextElement) {
    return myDelegate.isContextAccepted(contextElement);
  }

  public LanguageFileType getFileType() {
    return myDelegate.getFileType();
  }

  @Override
  public EvaluatorBuilder getEvaluatorBuilder() {
    return myDelegate.getEvaluatorBuilder();
  }
  
  private PsiElement wrapContext(Project project, final PsiElement originalContext) {
    if (project.isDefault()) return originalContext;
    PsiElement context = originalContext;
    XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
    if (session != null) {
      XValueMarkers<?, ?> markers = ((XDebugSessionImpl)session).getValueMarkers();
      Map<?, ValueMarkup> markupMap = markers != null ? markers.getAllMarkers() : null;
      //final Map<ObjectReference, ValueMarkup> markupMap = ValueDescriptorImpl.getMarkupMap(process);
      if (markupMap != null && markupMap.size() > 0) {
        final Pair<String, Map<String, ObjectReference>> markupVariables = createMarkupVariablesText(markupMap);
        int offset = markupVariables.getFirst().length() - 1;
        final TextWithImportsImpl textWithImports = new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, markupVariables.getFirst(), "", myDelegate.getFileType());
        final JavaCodeFragment codeFragment = myDelegate.createCodeFragment(textWithImports, context, project);
        codeFragment.accept(new JavaRecursiveElementVisitor() {
          public void visitLocalVariable(PsiLocalVariable variable) {
            final String name = variable.getName();
            variable.putUserData(LABEL_VARIABLE_VALUE_KEY, markupVariables.getSecond().get(name));
          }
        });
        final PsiElement newContext = codeFragment.findElementAt(offset);
        if (newContext != null) {
          context = newContext;
        }
      }
    }
    return context;
  }
  
  private static Pair<String, Map<String, ObjectReference>> createMarkupVariablesText(Map<?, ValueMarkup> markupMap) {
    final Map<String, ObjectReference> reverseMap = new HashMap<String, ObjectReference>();
    final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
    try {
      for (Map.Entry<?, ValueMarkup> entry : markupMap.entrySet()) {
        ObjectReference objectRef = (ObjectReference)entry.getKey();
        final ValueMarkup markup = entry.getValue();
        String labelName = markup.getText();
        if (!StringUtil.isJavaIdentifier(labelName)) {
          continue;
        }
        try {
          final String typeName = objectRef.type().name();
          labelName += DEBUG_LABEL_SUFFIX;
          if (buffer.length() > 0) {
            buffer.append("\n");
          }
          buffer.append(typeName).append(" ").append(labelName).append(";");
          reverseMap.put(labelName, objectRef);
        }
        catch (ObjectCollectedException e) {
          //it.remove();
        }
      }
      buffer.append(" ");
      return Pair.create(buffer.toString(), reverseMap);
    }
    finally {
      StringBuilderSpinAllocator.dispose(buffer);
    }
  }
}
