/*
 * JDB - Java Debugger
 * Copyright 2017 Johnny Cao
 *
 * 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.gmail.woodyc40.topics.cmd;

import com.gmail.woodyc40.topics.infra.JvmContext;
import com.gmail.woodyc40.topics.infra.command.CmdProcessor;
import com.sun.jdi.*;
import com.sun.jdi.event.BreakpointEvent;

import java.util.Map;

public class Inspect implements CmdProcessor {
    @Override
    public String name() {
        return "inspect";
    }

    @Override
    public String help() {
        return "Inspects the current object state at a breakpoint";
    }

    @Override
    public String[] aliases() {
        return new String[] { "i" };
    }

    @Override
    public void process(String alias, String[] args) {
        try {
            if (args.length == 0) {
                inspect("all");
            } else {
                for (String s : args) {
                    inspect(s);
                }
            }
        } catch (IncompatibleThreadStateException | AbsentInformationException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Inspects the variables at the current breakpoint with
     * the given scope between all, stack, and instance
     * visible.
     *
     * @param scope the scope to inspect
     * @throws IncompatibleThreadStateException not sure
     * what this means but it shouldn't happen lol
     * @throws AbsentInformationException if the JVM is not
     * setup to send stack info
     */
    private static void inspect(String scope) throws IncompatibleThreadStateException, AbsentInformationException {
        BreakpointEvent event;
        synchronized (JvmContext.getContext().getLock()) {
            event = JvmContext.getContext().getCurrentBreakpoint();
        }

        if (event == null) {
            System.out.println("no breakpoint");
            return;
        }

        // TODO
        switch (scope) {
            case "all":
                StackFrame frame = event.thread().frame(0);
                for (Map.Entry<LocalVariable, Value> entry : frame.getValues(frame.visibleVariables()).entrySet()) {
                    System.out.println(entry.getKey().name() + " = " + entry.getValue());
                }
                break;
            case "stack":

                break;
            case "class":

                break;
            case "inst":
            case "instance":

                break;
            default:
                System.out.println("unrecognized scope " + scope);
                break;
        }
    }
}
@@ -2653,41 +2653,230 @@
     
-System.out.println(entry.getKey()
+LocalVariable var = entry.getKey();%0A                    if (entry.getValue() == null) %7B%0A                        continue;%0A                    %7D%0A                    System.out.println(trimPackage(var.typeName()) + ' ' + var
 .nam
@@ -3103,17 +3103,16 @@
 tance%22:%0A
-%0A
         
@@ -3229,32 +3229,32 @@
          break;%0A
-
         %7D%0A    %7D%0A
@@ -3252,10 +3252,346 @@
  %7D%0A    %7D
+%0A%0A    /**%0A     * Removes the package from an FQN name, if it exists.%0A     *%0A     * @param typeName the type name to trim%0A     * @return the trimmed string%0A     */%0A    private static String trimPackage(String typeName) %7B%0A        int idx = typeName.lastIndexOf('.');%0A        return idx %3E -1 ? typeName.substring(idx + 1) : typeName;%0A    %7D
 %0A%7D

Fix minor null bug