/*
 * 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.
 */
package com.intellij.debugger.ui.tree.render;

import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.engine.jdi.StackFrameProxy;
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiExpression;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xdebugger.settings.XDebuggerSettingsManager;
import com.sun.jdi.*;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * User: lex
 * Date: Sep 17, 2003
 * Time: 2:04:00 PM
 */
public class ClassRenderer extends NodeRendererImpl{
  private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ClassRenderer");
  
  public static final @NonNls String UNIQUE_ID = "ClassRenderer";

  public boolean SHOW_SYNTHETICS = true;
  public boolean SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES = true;
  public boolean SHOW_STATIC = false;
  public boolean SHOW_STATIC_FINAL = false;

  public boolean SHOW_FQ_TYPE_NAMES = true;
  public boolean SHOW_DECLARED_TYPE = false;
  public boolean SHOW_OBJECT_ID = true;
  
  public ClassRenderer() {
    myProperties.setEnabled(true);
  }

  public final String renderTypeName(final String typeName) {
    if (SHOW_FQ_TYPE_NAMES) {
      return typeName;
    }
    final int dotIndex = typeName.lastIndexOf('.');
    if (dotIndex > 0) {
      return typeName.substring(dotIndex + 1);
    }
    return typeName;
  }

  @Override
  public String getUniqueId() {
    return UNIQUE_ID;
  }

  @Override
  public boolean isEnabled() {
    return myProperties.isEnabled();
  }

  @Override
  public void setEnabled(boolean enabled) {
    myProperties.setEnabled(enabled);
  }

  @Override
  public ClassRenderer clone() {
    return (ClassRenderer) super.clone();
  }

  @Override
  public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener)  throws EvaluateException {
    return calcLabel(descriptor);
  }

  protected static String calcLabel(ValueDescriptor descriptor) {
    final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor;
    final Value value = valueDescriptor.getValue();
    if (value instanceof ObjectReference) {
      final StringBuilder buf = StringBuilderSpinAllocator.alloc();
      try {
        if (value instanceof StringReference) {
          // no need to add quotes and escape characters here, XValueTextRendererImpl handles the presentation
          //buf.append('\"');
          //buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value()));
          //buf.append('\"');
          buf.append(((StringReference)value).value());
        }
        else if (value instanceof ClassObjectReference) {
          ReferenceType type = ((ClassObjectReference)value).reflectedType();
          buf.append((type != null)?type.name():"{...}");
        }
        else {
          final ObjectReference objRef = (ObjectReference)value;
          final Type type = objRef.type();
          if (type instanceof ClassType && ((ClassType)type).isEnum()) {
            final String name = getEnumConstantName(objRef, (ClassType)type);
            if (name != null) {
              buf.append(name);
            }
            else {
              buf.append(type.name());
            }
          }
          else {
            buf.append(ValueDescriptorImpl.getIdLabel(objRef));
          }
        }
        return buf.toString();
      }
      finally {
        StringBuilderSpinAllocator.dispose(buf);
      }
    }
    else if(value == null) {
      //noinspection HardCodedStringLiteral
      return "null";
    }
    else {
      return DebuggerBundle.message("label.undefined");
    }
  }

  @Override
  public void buildChildren(final Value value, final ChildrenBuilder builder, final EvaluationContext evaluationContext) {
    DebuggerManagerThreadImpl.assertIsManagerThread();
    final ValueDescriptorImpl parentDescriptor = (ValueDescriptorImpl)builder.getParentDescriptor();
    final NodeManager nodeManager = builder.getNodeManager();
    final NodeDescriptorFactory nodeDescriptorFactory = builder.getDescriptorManager();

    List<DebuggerTreeNode> children = new ArrayList<DebuggerTreeNode>();
    if (value instanceof ObjectReference) {
      final ObjectReference objRef = (ObjectReference)value;
      final ReferenceType refType = objRef.referenceType();
      // default ObjectReference processing
      final List<Field> fields = refType.allFields();
      if (fields.size() > 0) {
        for (final Field field : fields) {
          if (!shouldDisplay(evaluationContext, objRef, field)) {
            continue;
          }
          children.add(nodeManager.createNode(nodeDescriptorFactory.getFieldDescriptor(parentDescriptor, objRef, field), evaluationContext));
        }

        if (XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues()) {
          Collections.sort(children, NodeManagerImpl.getNodeComparator());
        }
      }
      else {
        children.add(nodeManager.createMessageNode(MessageDescriptor.CLASS_HAS_NO_FIELDS.getLabel()));
      }
    }
    builder.setChildren(children);
  }

  private boolean shouldDisplay(EvaluationContext context, @NotNull ObjectReference objInstance, @NotNull Field field) {
    final boolean isSynthetic = DebuggerUtils.isSynthetic(field);
    if (!SHOW_SYNTHETICS && isSynthetic) {
      return false;
    }
    if (SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES && isSynthetic) {
      try {
        final StackFrameProxy frameProxy = context.getFrameProxy();
        if (frameProxy != null) {
          final Location location = frameProxy.location();
          if (location != null && objInstance.equals(context.getThisObject()) && Comparing.equal(objInstance.referenceType(), location.declaringType()) && StringUtil.startsWith(field.name(), FieldDescriptorImpl.OUTER_LOCAL_VAR_FIELD_PREFIX)) {
            return false;
          }
        }
      }
      catch (EvaluateException ignored) {
      }
    }
    if(!SHOW_STATIC && field.isStatic()) {
      return false;
    }

    if(!SHOW_STATIC_FINAL && field.isStatic() && field.isFinal()) {
      return false;
    }

    return true;
  }

  @Override
  public void readExternal(Element element) throws InvalidDataException {
    super.readExternal(element);
    DefaultJDOMExternalizer.readExternal(this, element);
  }

  @Override
  public void writeExternal(Element element) throws WriteExternalException {
    super.writeExternal(element);
    DefaultJDOMExternalizer.writeExternal(this, element);
  }

  @Override
  public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException {
    FieldDescriptor fieldDescriptor = (FieldDescriptor)node.getDescriptor();

    PsiElementFactory elementFactory = JavaPsiFacade.getInstance(node.getProject()).getElementFactory();
    try {
      return elementFactory.createExpressionFromText(fieldDescriptor.getField().name(), DebuggerUtils.findClass(
        fieldDescriptor.getObject().referenceType().name(), context.getProject(), context.getDebugProcess().getSearchScope())
      );
    }
    catch (IncorrectOperationException e) {
      throw new EvaluateException(DebuggerBundle.message("error.invalid.field.name", fieldDescriptor.getField().name()), null);
    }
  }

  private static boolean valueExpandable(Value value)  {
    try {
      if(value instanceof ArrayReference) {
        return ((ArrayReference)value).length() > 0;
      }
      else if(value instanceof ObjectReference) {
        return ((ObjectReference)value).referenceType().allFields().size() > 0;
      }
    }
    catch (ObjectCollectedException e) {
      return true;
    }

    return false;
  }

  @Override
  public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) {
    DebuggerManagerThreadImpl.assertIsManagerThread();
    return valueExpandable(value);
  }

  @Override
  public boolean isApplicable(Type type) {
    return type instanceof ReferenceType && !(type instanceof ArrayType);
  }

  @Override
  public @NonNls String getName() {
    return "Object";
  }

  @Override
  public void setName(String text) {
    LOG.assertTrue(false);
  }

  @Nullable
  public static String getEnumConstantName(final ObjectReference objRef, ClassType classType) {
    do {
      if (!classType.isPrepared()) {
        return null;
      }
      classType = classType.superclass();
      if (classType == null) {
        return null;
      }
    }
    while (!("java.lang.Enum".equals(classType.name())));
    //noinspection HardCodedStringLiteral
    final Field field = classType.fieldByName("name");
    if (field == null) {
      return null;
    }
    final Value value = objRef.getValue(field);
    if (!(value instanceof StringReference)) {
      return null;
    }
    return ((StringReference)value).value();
  }
}
