/*
 * Copyright 2006 The Android Open Source Project
 *
 * JDWP spy.  This is a rearranged version of the JDWP code from the VM.
 */
#include "Common.h"
#include "jdwp/jdwp_constants.h"

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h>
#include <errno.h>
#include <assert.h>

#include <iostream>
#include <sstream>

#define kInputBufferSize    (256*1024)

#define kMagicHandshakeLen  14      /* "JDWP-Handshake" */
#define kJDWPHeaderLen      11
#define kJDWPFlagReply      0x80


/*
 * Information about the remote end.
 */
struct Peer {
    char    label[2];           /* 'D' or 'V' */

    int     sock;
    unsigned char   inputBuffer[kInputBufferSize];
    int     inputCount;

    bool    awaitingHandshake;  /* waiting for "JDWP-Handshake" */
};


/*
 * Network state.
 */
struct NetState {
    /* listen here for connection from debugger */
    int     listenSock;

    /* connect here to contact VM */
    struct in_addr vmAddr;
    uint16_t vmPort;

    Peer    dbg;
    Peer    vm;
};

/*
 * Function names.
 */
struct JdwpHandlerMap {
    u1  cmdSet;
    u1  cmd;
    const char* descr;
};

/*
 * Map commands to names.
 *
 * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
 * and 128-256 are vendor-defined.
 */
static const JdwpHandlerMap gHandlerMap[] = {
    /* VirtualMachine command set (1) */
    { 1,    1,  "VirtualMachine.Version" },
    { 1,    2,  "VirtualMachine.ClassesBySignature" },
    { 1,    3,  "VirtualMachine.AllClasses" },
    { 1,    4,  "VirtualMachine.AllThreads" },
    { 1,    5,  "VirtualMachine.TopLevelThreadGroups" },
    { 1,    6,  "VirtualMachine.Dispose" },
    { 1,    7,  "VirtualMachine.IDSizes" },
    { 1,    8,  "VirtualMachine.Suspend" },
    { 1,    9,  "VirtualMachine.Resume" },
    { 1,    10, "VirtualMachine.Exit" },
    { 1,    11, "VirtualMachine.CreateString" },
    { 1,    12, "VirtualMachine.Capabilities" },
    { 1,    13, "VirtualMachine.ClassPaths" },
    { 1,    14, "VirtualMachine.DisposeObjects" },
    { 1,    15, "VirtualMachine.HoldEvents" },
    { 1,    16, "VirtualMachine.ReleaseEvents" },
    { 1,    17, "VirtualMachine.CapabilitiesNew" },
    { 1,    18, "VirtualMachine.RedefineClasses" },
    { 1,    19, "VirtualMachine.SetDefaultStratum" },
    { 1,    20, "VirtualMachine.AllClassesWithGeneric"},
    { 1,    21, "VirtualMachine.InstanceCounts"},

    /* ReferenceType command set (2) */
    { 2,    1,  "ReferenceType.Signature" },
    { 2,    2,  "ReferenceType.ClassLoader" },
    { 2,    3,  "ReferenceType.Modifiers" },
    { 2,    4,  "ReferenceType.Fields" },
    { 2,    5,  "ReferenceType.Methods" },
    { 2,    6,  "ReferenceType.GetValues" },
    { 2,    7,  "ReferenceType.SourceFile" },
    { 2,    8,  "ReferenceType.NestedTypes" },
    { 2,    9,  "ReferenceType.Status" },
    { 2,    10, "ReferenceType.Interfaces" },
    { 2,    11, "ReferenceType.ClassObject" },
    { 2,    12, "ReferenceType.SourceDebugExtension" },
    { 2,    13, "ReferenceType.SignatureWithGeneric" },
    { 2,    14, "ReferenceType.FieldsWithGeneric" },
    { 2,    15, "ReferenceType.MethodsWithGeneric" },
    { 2,    16, "ReferenceType.Instances" },
    { 2,    17, "ReferenceType.ClassFileVersion" },
    { 2,    18, "ReferenceType.ConstantPool" },

    /* ClassType command set (3) */
    { 3,    1,  "ClassType.Superclass" },
    { 3,    2,  "ClassType.SetValues" },
    { 3,    3,  "ClassType.InvokeMethod" },
    { 3,    4,  "ClassType.NewInstance" },

    /* ArrayType command set (4) */
    { 4,    1,  "ArrayType.NewInstance" },

    /* InterfaceType command set (5) */

    /* Method command set (6) */
    { 6,    1,  "Method.LineTable" },
    { 6,    2,  "Method.VariableTable" },
    { 6,    3,  "Method.Bytecodes" },
    { 6,    4,  "Method.IsObsolete" },
    { 6,    5,  "Method.VariableTableWithGeneric" },

    /* Field command set (8) */

    /* ObjectReference command set (9) */
    { 9,    1,  "ObjectReference.ReferenceType" },
    { 9,    2,  "ObjectReference.GetValues" },
    { 9,    3,  "ObjectReference.SetValues" },
    { 9,    4,  "ObjectReference.UNUSED" },
    { 9,    5,  "ObjectReference.MonitorInfo" },
    { 9,    6,  "ObjectReference.InvokeMethod" },
    { 9,    7,  "ObjectReference.DisableCollection" },
    { 9,    8,  "ObjectReference.EnableCollection" },
    { 9,    9,  "ObjectReference.IsCollected" },
    { 9,    10, "ObjectReference.ReferringObjects" },

    /* StringReference command set (10) */
    { 10,   1,  "StringReference.Value" },

    /* ThreadReference command set (11) */
    { 11,   1,  "ThreadReference.Name" },
    { 11,   2,  "ThreadReference.Suspend" },
    { 11,   3,  "ThreadReference.Resume" },
    { 11,   4,  "ThreadReference.Status" },
    { 11,   5,  "ThreadReference.ThreadGroup" },
    { 11,   6,  "ThreadReference.Frames" },
    { 11,   7,  "ThreadReference.FrameCount" },
    { 11,   8,  "ThreadReference.OwnedMonitors" },
    { 11,   9,  "ThreadReference.CurrentContendedMonitor" },
    { 11,   10, "ThreadReference.Stop" },
    { 11,   11, "ThreadReference.Interrupt" },
    { 11,   12, "ThreadReference.SuspendCount" },
    { 11,   13, "ThreadReference.OwnedMonitorsStackDepthInfo" },
    { 11,   14, "ThreadReference.ForceEarlyReturn" },

    /* ThreadGroupReference command set (12) */
    { 12,   1,  "ThreadGroupReference.Name" },
    { 12,   2,  "ThreadGroupReference.Parent" },
    { 12,   3,  "ThreadGroupReference.Children" },

    /* ArrayReference command set (13) */
    { 13,   1,  "ArrayReference.Length" },
    { 13,   2,  "ArrayReference.GetValues" },
    { 13,   3,  "ArrayReference.SetValues" },

    /* ClassLoaderReference command set (14) */
    { 14,   1,  "ArrayReference.VisibleClasses" },

    /* EventRequest command set (15) */
    { 15,   1,  "EventRequest.Set" },
    { 15,   2,  "EventRequest.Clear" },
    { 15,   3,  "EventRequest.ClearAllBreakpoints" },

    /* StackFrame command set (16) */
    { 16,   1,  "StackFrame.GetValues" },
    { 16,   2,  "StackFrame.SetValues" },
    { 16,   3,  "StackFrame.ThisObject" },
    { 16,   4,  "StackFrame.PopFrames" },

    /* ClassObjectReference command set (17) */
    { 17,   1,  "ClassObjectReference.ReflectedType" },

    /* Event command set (64) */
    { 64,  100, "Event.Composite" },

    /* DDMS */
    { 199,  1,  "DDMS.Chunk" },
};

/*
 * Look up a command's name.
 */
static const char* getCommandName(int cmdSet, int cmd)
{
    for (int i = 0; i < (int) NELEM(gHandlerMap); i++) {
        if (gHandlerMap[i].cmdSet == cmdSet &&
            gHandlerMap[i].cmd == cmd)
        {
            return gHandlerMap[i].descr;
        }
    }

    return "?UNKNOWN?";
}


void jdwpNetFree(NetState* netState);       /* fwd */

/*
 * Allocate state structure and bind to the listen port.
 *
 * Returns 0 on success.
 */
NetState* jdwpNetStartup(uint16_t listenPort, const char* connectHost, uint16_t connectPort) {
    NetState* netState = new NetState;
    memset(netState, 0, sizeof(*netState));
    netState->listenSock = -1;
    netState->dbg.sock = netState->vm.sock = -1;

    strcpy(netState->dbg.label, "D");
    strcpy(netState->vm.label, "V");

    /*
     * Set up a socket to listen for connections from the debugger.
     */

    netState->listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (netState->listenSock < 0) {
        fprintf(stderr, "Socket create failed: %s\n", strerror(errno));
        goto fail;
    }

    /* allow immediate re-use if we die */
    {
        int one = 1;
        if (setsockopt(netState->listenSock, SOL_SOCKET, SO_REUSEADDR, &one,
                sizeof(one)) < 0)
        {
            fprintf(stderr, "setsockopt(SO_REUSEADDR) failed: %s\n",
                strerror(errno));
            goto fail;
        }
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(listenPort);
    addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(netState->listenSock, (struct sockaddr*) &addr, sizeof(addr)) != 0)
    {
        fprintf(stderr, "attempt to bind to port %u failed: %s\n",
            listenPort, strerror(errno));
        goto fail;
    }

    fprintf(stderr, "+++ bound to port %u\n", listenPort);

    if (listen(netState->listenSock, 5) != 0) {
        fprintf(stderr, "Listen failed: %s\n", strerror(errno));
        goto fail;
    }

    /*
     * Do the hostname lookup for the VM.
     */
    struct hostent* pHost;

    pHost = gethostbyname(connectHost);
    if (pHost == NULL) {
        fprintf(stderr, "Name lookup of '%s' failed: %s\n",
            connectHost, strerror(h_errno));
        goto fail;
    }

    netState->vmAddr = *((struct in_addr*) pHost->h_addr_list[0]);
    netState->vmPort = connectPort;

    fprintf(stderr, "+++ connect host resolved to %s\n",
        inet_ntoa(netState->vmAddr));

    return netState;

fail:
    jdwpNetFree(netState);
    return NULL;
}

/*
 * Shut down JDWP listener.  Don't free state.
 *
 * Note that "netState" may be partially initialized if "startup" failed.
 */
void jdwpNetShutdown(NetState* netState)
{
    int listenSock = netState->listenSock;
    int dbgSock = netState->dbg.sock;
    int vmSock = netState->vm.sock;

    /* clear these out so it doesn't wake up and try to reuse them */
    /* (important when multi-threaded) */
    netState->listenSock = netState->dbg.sock = netState->vm.sock = -1;

    if (listenSock >= 0) {
        shutdown(listenSock, SHUT_RDWR);
        close(listenSock);
    }
    if (dbgSock >= 0) {
        shutdown(dbgSock, SHUT_RDWR);
        close(dbgSock);
    }
    if (vmSock >= 0) {
        shutdown(vmSock, SHUT_RDWR);
        close(vmSock);
    }
}

/*
 * Shut down JDWP listener and free its state.
 */
void jdwpNetFree(NetState* netState)
{
    if (netState == NULL)
        return;

    jdwpNetShutdown(netState);
    delete netState;
}

/*
 * Disable the TCP Nagle algorithm, which delays transmission of outbound
 * packets until the previous transmissions have been acked.  JDWP does a
 * lot of back-and-forth with small packets, so this may help.
 */
static int setNoDelay(int fd)
{
    int cc, on = 1;

    cc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
    assert(cc == 0);
    return cc;
}

/*
 * Accept a connection.  This will block waiting for somebody to show up.
 */
bool jdwpAcceptConnection(NetState* netState)
{
    struct sockaddr_in addr;
    socklen_t addrlen;
    int sock;

    if (netState->listenSock < 0)
        return false;       /* you're not listening! */

    assert(netState->dbg.sock < 0);     /* must not already be talking */

    addrlen = sizeof(addr);
    do {
        sock = accept(netState->listenSock, (struct sockaddr*) &addr, &addrlen);
        if (sock < 0 && errno != EINTR) {
            fprintf(stderr, "accept failed: %s\n", strerror(errno));
            return false;
        }
    } while (sock < 0);

    fprintf(stderr, "+++ accepted connection from %s:%u\n",
        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

    netState->dbg.sock = sock;
    netState->dbg.awaitingHandshake = true;
    netState->dbg.inputCount = 0;

    setNoDelay(sock);

    return true;
}

/*
 * Close the connections to the debugger and VM.
 *
 * Reset the state so we're ready to receive a new connection.
 */
void jdwpCloseConnection(NetState* netState)
{
    if (netState->dbg.sock >= 0) {
        fprintf(stderr, "+++ closing connection to debugger\n");
        close(netState->dbg.sock);
        netState->dbg.sock = -1;
    }
    if (netState->vm.sock >= 0) {
        fprintf(stderr, "+++ closing connection to vm\n");
        close(netState->vm.sock);
        netState->vm.sock = -1;
    }
}

/*
 * Figure out if we have a full packet in the buffer.
 */
static bool haveFullPacket(Peer* pPeer)
{
    long length;

    if (pPeer->awaitingHandshake)
        return (pPeer->inputCount >= kMagicHandshakeLen);

    if (pPeer->inputCount < 4)
        return false;

    length = get4BE(pPeer->inputBuffer);
    return (pPeer->inputCount >= length);
}

/*
 * Consume bytes from the buffer.
 *
 * This would be more efficient with a circular buffer.  However, we're
 * usually only going to find one packet, which is trivial to handle.
 */
static void consumeBytes(Peer* pPeer, int count)
{
    assert(count > 0);
    assert(count <= pPeer->inputCount);

    if (count == pPeer->inputCount) {
        pPeer->inputCount = 0;
        return;
    }

    memmove(pPeer->inputBuffer, pPeer->inputBuffer + count,
        pPeer->inputCount - count);
    pPeer->inputCount -= count;
}

/*
 * Get the current time.
 */
static void getCurrentTime(int* pMin, int* pSec)
{
    time_t now;
    struct tm* ptm;

    now = time(NULL);
    ptm = localtime(&now);
    *pMin = ptm->tm_min;
    *pSec = ptm->tm_sec;
}

/*
 * Dump the contents of a packet to stdout.
 */
static void dumpPacket(const unsigned char* packetBuf, const char* srcName,
    const char* dstName)
{
    const unsigned char* buf = packetBuf;
    char prefix[3];
    u4 length, id;
    u1 flags, cmdSet=0, cmd=0;
    art::JDWP::JdwpError error = art::JDWP::ERR_NONE;
    bool reply;
    int dataLen;

    length = get4BE(buf+0);
    id = get4BE(buf+4);
    flags = get1(buf+8);
    if ((flags & kJDWPFlagReply) != 0) {
        reply = true;
        error = static_cast<art::JDWP::JdwpError>(get2BE(buf+9));
    } else {
        reply = false;
        cmdSet = get1(buf+9);
        cmd = get1(buf+10);
    }

    buf += kJDWPHeaderLen;
    dataLen = length - (buf - packetBuf);

    if (!reply) {
        prefix[0] = srcName[0];
        prefix[1] = '>';
    } else {
        prefix[0] = dstName[0];
        prefix[1] = '<';
    }
    prefix[2] = '\0';

    int min, sec;
    getCurrentTime(&min, &sec);

    if (!reply) {
        printf("%s REQUEST dataLen=%-5u id=0x%08x flags=0x%02x cmd=%d/%d [%02d:%02d]\n",
            prefix, dataLen, id, flags, cmdSet, cmd, min, sec);
        printf("%s   --> %s\n", prefix, getCommandName(cmdSet, cmd));
    } else {
        std::ostringstream ss;
        ss << "TODO"; // get access to the operator<<, or regenerate it for jdwpspy?
        printf("%s REPLY   dataLen=%-5u id=0x%08x flags=0x%02x err=%d (%s) [%02d:%02d]\n",
            prefix, dataLen, id, flags, error, ss.str().c_str(), min,sec);
    }
    if (dataLen > 0)
        printHexDump2(buf, dataLen, prefix);
    printf("%s ----------\n", prefix);
}

/*
 * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
 */
static bool handlePacket(Peer* pDst, Peer* pSrc)
{
    const unsigned char* buf = pSrc->inputBuffer;
    u4 length;
    u1 flags;
    int cc;

    length = get4BE(buf+0);
    flags = get1(buf+9);

    assert((int) length <= pSrc->inputCount);

    dumpPacket(buf, pSrc->label, pDst->label);

    cc = write(pDst->sock, buf, length);
    if (cc != (int) length) {
        fprintf(stderr, "Failed sending packet: %s\n", strerror(errno));
        return false;
    }
    /*printf("*** wrote %d bytes from %c to %c\n",
        cc, pSrc->label[0], pDst->label[0]);*/

    consumeBytes(pSrc, length);
    return true;
}

/*
 * Handle incoming data.  If we have a full packet in the buffer, process it.
 */
static bool handleIncoming(Peer* pWritePeer, Peer* pReadPeer)
{
    if (haveFullPacket(pReadPeer)) {
        if (pReadPeer->awaitingHandshake) {
            printf("Handshake [%c]: %.14s\n",
                pReadPeer->label[0], pReadPeer->inputBuffer);
            if (write(pWritePeer->sock, pReadPeer->inputBuffer,
                    kMagicHandshakeLen) != kMagicHandshakeLen)
            {
                fprintf(stderr,
                    "+++ [%c] handshake write failed\n", pReadPeer->label[0]);
                goto fail;
            }
            consumeBytes(pReadPeer, kMagicHandshakeLen);
            pReadPeer->awaitingHandshake = false;
        } else {
            if (!handlePacket(pWritePeer, pReadPeer))
                goto fail;
        }
    } else {
        /*printf("*** %c not full yet\n", pReadPeer->label[0]);*/
    }

    return true;

fail:
    return false;
}

/*
 * Process incoming data.  If no data is available, this will block until
 * some arrives.
 *
 * Returns "false" on error (indicating that the connection has been severed).
 */
bool jdwpProcessIncoming(NetState* netState)
{
    int cc;

    assert(netState->dbg.sock >= 0);
    assert(netState->vm.sock >= 0);

    while (!haveFullPacket(&netState->dbg) && !haveFullPacket(&netState->vm)) {
        /* read some more */
        int highFd;
        fd_set readfds;

        highFd = (netState->dbg.sock > netState->vm.sock) ?
            netState->dbg.sock+1 : netState->vm.sock+1;
        FD_ZERO(&readfds);
        FD_SET(netState->dbg.sock, &readfds);
        FD_SET(netState->vm.sock, &readfds);

        errno = 0;
        cc = select(highFd, &readfds, NULL, NULL, NULL);
        if (cc < 0) {
            if (errno == EINTR) {
                fprintf(stderr, "+++ EINTR on select\n");
                continue;
            }
            fprintf(stderr, "+++ select failed: %s\n", strerror(errno));
            goto fail;
        }

        if (FD_ISSET(netState->dbg.sock, &readfds)) {
            cc = read(netState->dbg.sock,
                netState->dbg.inputBuffer + netState->dbg.inputCount,
                sizeof(netState->dbg.inputBuffer) - netState->dbg.inputCount);
            if (cc < 0) {
                if (errno == EINTR) {
                    fprintf(stderr, "+++ EINTR on read\n");
                    continue;
                }
                fprintf(stderr, "+++ dbg read failed: %s\n", strerror(errno));
                goto fail;
            }
            if (cc == 0) {
                if (sizeof(netState->dbg.inputBuffer) ==
                        netState->dbg.inputCount)
                    fprintf(stderr, "+++ debugger sent huge message\n");
                else
                    fprintf(stderr, "+++ debugger disconnected\n");
                goto fail;
            }

            /*printf("*** %d bytes from dbg\n", cc);*/
            netState->dbg.inputCount += cc;
        }

        if (FD_ISSET(netState->vm.sock, &readfds)) {
            cc = read(netState->vm.sock,
                netState->vm.inputBuffer + netState->vm.inputCount,
                sizeof(netState->vm.inputBuffer) - netState->vm.inputCount);
            if (cc < 0) {
                if (errno == EINTR) {
                    fprintf(stderr, "+++ EINTR on read\n");
                    continue;
                }
                fprintf(stderr, "+++ vm read failed: %s\n", strerror(errno));
                goto fail;
            }
            if (cc == 0) {
                if (sizeof(netState->vm.inputBuffer) ==
                        netState->vm.inputCount)
                    fprintf(stderr, "+++ vm sent huge message\n");
                else
                    fprintf(stderr, "+++ vm disconnected\n");
                goto fail;
            }

            /*printf("*** %d bytes from vm\n", cc);*/
            netState->vm.inputCount += cc;
        }
    }

    if (!handleIncoming(&netState->dbg, &netState->vm))
        goto fail;
    if (!handleIncoming(&netState->vm, &netState->dbg))
        goto fail;

    return true;

fail:
    jdwpCloseConnection(netState);
    return false;
}

/*
 * Connect to the VM.
 */
bool jdwpConnectToVm(NetState* netState)
{
    struct sockaddr_in addr;
    int sock = -1;

    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0) {
        fprintf(stderr, "Socket create failed: %s\n", strerror(errno));
        goto fail;
    }

    addr.sin_family = AF_INET;
    addr.sin_addr = netState->vmAddr;
    addr.sin_port = htons(netState->vmPort);
    if (connect(sock, (struct sockaddr*) &addr, sizeof(addr)) != 0) {
        fprintf(stderr, "Connection to %s:%u failed: %s\n",
            inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), strerror(errno));
        goto fail;
    }
    fprintf(stderr, "+++ connected to VM %s:%u\n",
        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

    netState->vm.sock = sock;
    netState->vm.awaitingHandshake = true;
    netState->vm.inputCount = 0;

    setNoDelay(netState->vm.sock);
    return true;

fail:
    if (sock >= 0)
        close(sock);
    return false;
}

/*
 * Establish network connections and start things running.
 *
 * We wait for a new connection from the debugger.  When one arrives we
 * open a connection to the VM.  If one side or the other goes away, we
 * drop both ends and go back to listening.
 */
int run(const char* connectHost, int connectPort, int listenPort)
{
    NetState* state;

    state = jdwpNetStartup(listenPort, connectHost, connectPort);
    if (state == NULL)
        return -1;

    while (true) {
        if (!jdwpAcceptConnection(state))
            break;

        if (jdwpConnectToVm(state)) {
            while (true) {
                if (!jdwpProcessIncoming(state))
                    break;
            }
        }

        jdwpCloseConnection(state);
    }

    jdwpNetFree(state);

    return 0;
}
