package org.jetbrains.debugger;

import com.intellij.openapi.util.ActionCallback;
import com.intellij.util.Consumer;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.XCompositeNode;
import com.intellij.xdebugger.frame.XValueChildrenList;
import com.intellij.xdebugger.frame.XValueGroup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;

import java.util.List;

public class ScopeVariablesGroup extends XValueGroup {
  private final Scope scope;
  private final VariableContext context;

  private final CallFrame callFrame;

  public ScopeVariablesGroup(@NotNull final Scope scope, @NotNull final VariableContext context, @Nullable CallFrame callFrame) {
    super(createScopeNodeName(scope));

    this.scope = scope;

    if (callFrame == null || scope.getType() == Scope.Type.LIBRARY) {
      // functions scopes - we can watch variables only from global scope
      this.context = new ParentlessVariableContext(context, scope, scope.getType() == Scope.Type.GLOBAL);
    }
    else {
      this.context = new VariableContextWrapper(context, scope);
    }

    this.callFrame = scope.getType() == Scope.Type.LOCAL ? callFrame : null;
  }

  @TestOnly
  @NotNull
  public Scope getScope() {
    return scope;
  }

  public static void createAndAddScopeList(@NotNull XCompositeNode node, @NotNull List<Scope> scopes, @NotNull VariableContext context, @Nullable CallFrame callFrame) {
    XValueChildrenList list = new XValueChildrenList(scopes.size());
    for (Scope scope : scopes) {
      list.addTopGroup(new ScopeVariablesGroup(scope, context, callFrame));
    }
    node.addChildren(list, true);
  }

  private static String createScopeNodeName(@NotNull Scope scope) {
    switch (scope.getType()) {
      case GLOBAL:
        return XDebuggerBundle.message("scope.global");
      case LOCAL:
        return XDebuggerBundle.message("scope.local");
      case WITH:
        return XDebuggerBundle.message("scope.with");
      case CLOSURE:
        return XDebuggerBundle.message("scope.closure");
      case CATCH:
        return XDebuggerBundle.message("scope.catch");
      case LIBRARY:
        return XDebuggerBundle.message("scope.library");
      case INSTANCE:
        return XDebuggerBundle.message("scope.instance");
      case CLASS:
        return XDebuggerBundle.message("scope.class");
      case UNKNOWN:
        return XDebuggerBundle.message("scope.unknown");
      default:
        throw new IllegalArgumentException(scope.getType().name());
    }
  }

  @Override
  public boolean isAutoExpand() {
    return scope.getType() == Scope.Type.LOCAL || scope.getType() == Scope.Type.CATCH;
  }

  @Nullable
  @Override
  public String getComment() {
    String className = scope.getDescription();
    return "Object".equals(className) ? null : className;
  }

  @Override
  public void computeChildren(final @NotNull XCompositeNode node) {
    ActionCallback callback = callFrame == null ? null : new ActionCallback().doWhenDone(new Runnable() {
      @Override
      public void run() {
        if (node.isObsolete()) {
          return;
        }

        callFrame.getReceiverVariable().doWhenDone(new Consumer<Variable>() {
          @Override
          public void consume(Variable variable) {
            if (!node.isObsolete()) {
              node.addChildren(variable == null ? XValueChildrenList.EMPTY : XValueChildrenList.singleton(CallFrameBase.RECEIVER_NAME, new VariableView(variable, context)), true);
            }
          }
        }).doWhenRejected(new Consumer<String>() {
          @Override
          public void consume(@Nullable String error) {
            if (!node.isObsolete()) {
              node.addChildren(XValueChildrenList.EMPTY, true);
            }
          }
        });
      }
    });
    Variables.processScopeVariables(scope, node, context, callback);
  }

  private static final class ParentlessVariableContext extends VariableContextWrapper {
    private final boolean watchableAsEvaluationExpression;

    public ParentlessVariableContext(@NotNull VariableContext parentContext, @NotNull Scope scope, boolean watchableAsEvaluationExpression) {
      super(parentContext, scope);

      this.watchableAsEvaluationExpression = watchableAsEvaluationExpression;
    }

    @Override
    public boolean watchableAsEvaluationExpression() {
      return watchableAsEvaluationExpression;
    }

    @Nullable
    @Override
    public VariableContext getParent() {
      return null;
    }
  }
}