/*
 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot;

import sun.jvm.hotspot.*;
import sun.jvm.hotspot.debugger.*;

import java.io.*;
import java.util.*;

public class CLHSDB {

    public CLHSDB(JVMDebugger d) {
        jvmDebugger = d;
    }

    public static void main(String[] args) {
        new CLHSDB(args).run();
    }

    public void run() {
        // If jvmDebugger is already set, we have been given a JVMDebugger.
        // Otherwise, if pidText != null we are supposed to attach to it.
        // Finally, if execPath != null, it is the path of a jdk/bin/java
        // and coreFilename is the pathname of a core file we are
        // supposed to attach to.

        agent = new HotSpotAgent();

        Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
                public void run() {
                    detachDebugger();
                }
            });

        if (jvmDebugger != null) {
            attachDebugger(jvmDebugger);
        } else if (pidText != null) {
            attachDebugger(pidText);
        } else if (execPath != null) {
            attachDebugger(execPath, coreFilename);
        }


        CommandProcessor.DebuggerInterface di = new CommandProcessor.DebuggerInterface() {
                public HotSpotAgent getAgent() {
                    return agent;
                }
                public boolean isAttached() {
                    return attached;
                }
                public void attach(String pid) {
                    attachDebugger(pid);
                }
                public void attach(String java, String core) {
                    attachDebugger(java, core);
                }
                public void detach() {
                    detachDebugger();
                }
                public void reattach() {
                    if (attached) {
                        detachDebugger();
                    }
                    if (pidText != null) {
                        attach(pidText);
                    } else {
                        attach(execPath, coreFilename);
                    }
                }
            };


        BufferedReader in =
            new BufferedReader(new InputStreamReader(System.in));
        CommandProcessor cp = new CommandProcessor(di, in, System.out, System.err);
        cp.run(true);

    }

    //--------------------------------------------------------------------------------
    // Internals only below this point
    //
    private HotSpotAgent agent;
    private JVMDebugger jvmDebugger;
    private boolean      attached;
    // These had to be made data members because they are referenced in inner classes.
    private String pidText;
    private int pid;
    private String execPath;
    private String coreFilename;

    private void doUsage() {
        System.out.println("Usage:  java CLHSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]");
        System.out.println("           pid:                     attach to the process whose id is 'pid'");
        System.out.println("           path-to-java-executable: Debug a core file produced by this program");
        System.out.println("           path-to-corefile:        Debug this corefile.  The default is 'core'");
        System.out.println("        If no arguments are specified, you can select what to do from the GUI.\n");
        HotSpotAgent.showUsage();
    }

    private CLHSDB(String[] args) {
        switch (args.length) {
        case (0):
            break;

        case (1):
            if (args[0].equals("help") || args[0].equals("-help")) {
                doUsage();
                return;
            }
            // If all numbers, it is a PID to attach to
            // Else, it is a pathname to a .../bin/java for a core file.
            try {
                int unused = Integer.parseInt(args[0]);
                // If we get here, we have a PID and not a core file name
                pidText = args[0];
            } catch (NumberFormatException e) {
                execPath = args[0];
                coreFilename = "core";
            }
            break;

        case (2):
            execPath = args[0];
            coreFilename = args[1];
            break;

        default:
            System.out.println("HSDB Error: Too many options specified");
            doUsage();
            return;
        }
    }

    private void attachDebugger(JVMDebugger d) {
        agent.attach(d);
        attached = true;
     }

    /** NOTE we are in a different thread here than either the main
        thread or the Swing/AWT event handler thread, so we must be very
        careful when creating or removing widgets */
    private void attachDebugger(String pidText) {
        try {
            this.pidText = pidText;
            pid = Integer.parseInt(pidText);
        }
        catch (NumberFormatException e) {
            System.err.print("Unable to parse process ID \"" + pidText + "\".\nPlease enter a number.");
        }

        try {
            System.err.println("Attaching to process " + pid + ", please wait...");

            // FIXME: display exec'd debugger's output messages during this
            // lengthy call
            agent.attach(pid);
            attached = true;
        }
        catch (DebuggerException e) {
            final String errMsg = formatMessage(e.getMessage(), 80);
            System.err.println("Unable to connect to process ID " + pid + ":\n\n" + errMsg);
            agent.detach();
            e.printStackTrace();
            return;
        }
    }

    /** NOTE we are in a different thread here than either the main
        thread or the Swing/AWT event handler thread, so we must be very
        careful when creating or removing widgets */
    private void attachDebugger(final String executablePath, final String corePath) {
        // Try to open this core file
        try {
            System.err.println("Opening core file, please wait...");

            // FIXME: display exec'd debugger's output messages during this
            // lengthy call
            agent.attach(executablePath, corePath);
            attached = true;
        }
        catch (DebuggerException e) {
            final String errMsg = formatMessage(e.getMessage(), 80);
            System.err.println("Unable to open core file\n" + corePath + ":\n\n" + errMsg);
            agent.detach();
            e.printStackTrace();
            return;
        }
    }

    /** NOTE we are in a different thread here than either the main
        thread or the Swing/AWT event handler thread, so we must be very
        careful when creating or removing widgets */
    private void connect(final String remoteMachineName) {
        // Try to open this core file
        try {
            System.err.println("Connecting to debug server, please wait...");
            agent.attach(remoteMachineName);
            attached = true;
        }
        catch (DebuggerException e) {
            final String errMsg = formatMessage(e.getMessage(), 80);
            System.err.println("Unable to connect to machine \"" + remoteMachineName + "\":\n\n" + errMsg);
            agent.detach();
            e.printStackTrace();
            return;
        }
    }

    private void detachDebugger() {
        if (!attached) {
            return;
        }
        agent.detach();
        attached = false;
    }

    private void detach() {
        detachDebugger();
    }

    /** Punctuates the given string with \n's where necessary to not
        exceed the given number of characters per line. Strips
        extraneous whitespace. */
    private String formatMessage(String message, int charsPerLine) {
        StringBuffer buf = new StringBuffer(message.length());
        StringTokenizer tokenizer = new StringTokenizer(message);
        int curLineLength = 0;
        while (tokenizer.hasMoreTokens()) {
            String tok = tokenizer.nextToken();
            if (curLineLength + tok.length() > charsPerLine) {
                buf.append('\n');
                curLineLength = 0;
            } else {
                if (curLineLength != 0) {
                    buf.append(' ');
                    ++curLineLength;
                }
            }
            buf.append(tok);
            curLineLength += tok.length();
        }
        return buf.toString();
    }
}
