/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.
 */

/*
 * JDWP initialization.
 */
#include "jdwp/JdwpPriv.h"
#include "Dalvik.h"
#include "Atomic.h"

#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>


static void* jdwpThreadStart(void* arg);


/*
 * Initialize JDWP.
 *
 * Does not return until JDWP thread is running, but may return before
 * the thread is accepting network connections.
 */
JdwpState* dvmJdwpStartup(const JdwpStartupParams* pParams)
{
    JdwpState* state = NULL;

    /* comment this out when debugging JDWP itself */
    android_setMinPriority(LOG_TAG, ANDROID_LOG_DEBUG);

    state = (JdwpState*) calloc(1, sizeof(JdwpState));

    state->params = *pParams;

    state->requestSerial = 0x10000000;
    state->eventSerial = 0x20000000;
    dvmDbgInitMutex(&state->threadStartLock);
    dvmDbgInitMutex(&state->attachLock);
    dvmDbgInitMutex(&state->serialLock);
    dvmDbgInitMutex(&state->eventLock);
    state->eventThreadId = 0;
    dvmDbgInitMutex(&state->eventThreadLock);
    dvmDbgInitCond(&state->threadStartCond);
    dvmDbgInitCond(&state->attachCond);
    dvmDbgInitCond(&state->eventThreadCond);

    switch (pParams->transport) {
    case kJdwpTransportSocket:
        // LOGD("prepping for JDWP over TCP\n");
        state->transport = dvmJdwpSocketTransport();
        break;
    case kJdwpTransportAndroidAdb:
        // LOGD("prepping for JDWP over ADB\n");
        state->transport = dvmJdwpAndroidAdbTransport();
        /* TODO */
        break;
    default:
        LOGE("Unknown transport %d\n", pParams->transport);
        assert(false);
        goto fail;
    }

    if (!dvmJdwpNetStartup(state, pParams))
        goto fail;

    /*
     * Grab a mutex or two before starting the thread.  This ensures they
     * won't signal the cond var before we're waiting.
     */
    dvmDbgLockMutex(&state->threadStartLock);
    if (pParams->suspend)
        dvmDbgLockMutex(&state->attachLock);

    /*
     * We have bound to a port, or are trying to connect outbound to a
     * debugger.  Create the JDWP thread and let it continue the mission.
     */
    if (!dvmCreateInternalThread(&state->debugThreadHandle, "JDWP",
            jdwpThreadStart, state))
    {
        /* state is getting tossed, but unlock these anyway for cleanliness */
        dvmDbgUnlockMutex(&state->threadStartLock);
        if (pParams->suspend)
            dvmDbgUnlockMutex(&state->attachLock);
        goto fail;
    }

    /*
     * Wait until the thread finishes basic initialization.
     * TODO: cond vars should be waited upon in a loop
     */
    dvmDbgCondWait(&state->threadStartCond, &state->threadStartLock);
    dvmDbgUnlockMutex(&state->threadStartLock);


    /*
     * For suspend=y, wait for the debugger to connect to us or for us to
     * connect to the debugger.
     *
     * The JDWP thread will signal us when it connects successfully or
     * times out (for timeout=xxx), so we have to check to see what happened
     * when we wake up.
     */
    if (pParams->suspend) {
        dvmChangeStatus(NULL, THREAD_VMWAIT);
        dvmDbgCondWait(&state->attachCond, &state->attachLock);
        dvmDbgUnlockMutex(&state->attachLock);
        dvmChangeStatus(NULL, THREAD_RUNNING);

        if (!dvmJdwpIsActive(state)) {
            LOGE("JDWP connection failed\n");
            goto fail;
        }

        LOGI("JDWP connected\n");

        /*
         * Ordinarily we would pause briefly to allow the debugger to set
         * breakpoints and so on, but for "suspend=y" the VM init code will
         * pause the VM when it sends the VM_START message.
         */
    }

    return state;

fail:
    dvmJdwpShutdown(state);     // frees state
    return NULL;
}

/*
 * Reset all session-related state.  There should not be an active connection
 * to the client at this point.  The rest of the VM still thinks there is
 * a debugger attached.
 *
 * This includes freeing up the debugger event list.
 */
void dvmJdwpResetState(JdwpState* state)
{
    /* could reset the serial numbers, but no need to */

    dvmJdwpUnregisterAll(state);
    assert(state->eventList == NULL);

    /*
     * Should not have one of these in progress.  If the debugger went away
     * mid-request, though, we could see this.
     */
    if (state->eventThreadId != 0) {
        LOGW("WARNING: resetting state while event in progress\n");
        assert(false);
    }
}

/*
 * Tell the JDWP thread to shut down.  Frees "state".
 */
void dvmJdwpShutdown(JdwpState* state)
{
    void* threadReturn;

    if (state == NULL)
        return;

    if (dvmJdwpIsTransportDefined(state)) {
        if (dvmJdwpIsConnected(state))
            dvmJdwpPostVMDeath(state);

        /*
         * Close down the network to inspire the thread to halt.
         */
        if (gDvm.verboseShutdown)
            LOGD("JDWP shutting down net...\n");
        dvmJdwpNetShutdown(state);

        if (state->debugThreadStarted) {
            state->run = false;
            if (pthread_join(state->debugThreadHandle, &threadReturn) != 0) {
                LOGW("JDWP thread join failed\n");
            }
        }

        if (gDvm.verboseShutdown)
            LOGD("JDWP freeing netstate...\n");
        dvmJdwpNetFree(state);
        state->netState = NULL;
    }
    assert(state->netState == NULL);

    dvmJdwpResetState(state);
    free(state);
}

/*
 * Are we talking to a debugger?
 */ 
bool dvmJdwpIsActive(JdwpState* state)
{
    return dvmJdwpIsConnected(state);
}

/*
 * Entry point for JDWP thread.  The thread was created through the VM
 * mechanisms, so there is a java/lang/Thread associated with us.
 */
static void* jdwpThreadStart(void* arg)
{
    JdwpState* state = (JdwpState*) arg;

    LOGV("JDWP: thread running\n");

    /*
     * Finish initializing "state", then notify the creating thread that
     * we're running.
     */
    state->debugThreadHandle = dvmThreadSelf()->handle;
    state->run = true;
    MEM_BARRIER();
    state->debugThreadStarted = true;       // touch this last

    dvmDbgLockMutex(&state->threadStartLock);
    dvmDbgCondBroadcast(&state->threadStartCond);
    dvmDbgUnlockMutex(&state->threadStartLock);

    /* set the thread state to VMWAIT so GCs don't wait for us */
    dvmDbgThreadWaiting();

    /*
     * Loop forever if we're in server mode, processing connections.  In
     * non-server mode, we bail out of the thread when the debugger drops
     * us.
     *
     * We broadcast a notification when a debugger attaches, after we
     * successfully process the handshake.
     */
    while (state->run) {
        bool first;

        if (state->params.server) {
            /*
             * Block forever, waiting for a connection.  To support the
             * "timeout=xxx" option we'll need to tweak this.
             */
            if (!dvmJdwpAcceptConnection(state))
                break;
        } else {
            /*
             * If we're not acting as a server, we need to connect out to the
             * debugger.  To support the "timeout=xxx" option we need to
             * have a timeout if the handshake reply isn't received in a
             * reasonable amount of time.
             */
            if (!dvmJdwpEstablishConnection(state)) {
                /* wake anybody who was waiting for us to succeed */
                dvmDbgLockMutex(&state->attachLock);
                dvmDbgCondBroadcast(&state->attachCond);
                dvmDbgUnlockMutex(&state->attachLock);
                break;
            }
        }

        /* prep debug code to handle the new connection */
        dvmDbgConnected();

        /* process requests until the debugger drops */
        first = true;
        while (true) {
            // sanity check -- shouldn't happen?
            if (dvmThreadSelf()->status != THREAD_VMWAIT) {
                LOGE("JDWP thread no longer in VMWAIT (now %d); resetting\n",
                    dvmThreadSelf()->status);
                dvmDbgThreadWaiting();
            }

            if (!dvmJdwpProcessIncoming(state))     /* blocking read */
                break;

            if (first && !dvmJdwpAwaitingHandshake(state)) {
                /* handshake worked, tell the interpreter that we're active */
                first = false;

                /* set thread ID; requires object registry to be active */
                state->debugThreadId = dvmDbgGetThreadSelfId();

                /* wake anybody who's waiting for us */
                dvmDbgLockMutex(&state->attachLock);
                dvmDbgCondBroadcast(&state->attachCond);
                dvmDbgUnlockMutex(&state->attachLock);
            }
        }

        dvmJdwpCloseConnection(state);

        if (state->ddmActive) {
            state->ddmActive = false;

            /* broadcast the disconnect; must be in RUNNING state */
            dvmDbgThreadRunning();
            dvmDbgDdmDisconnected();
            dvmDbgThreadWaiting();
        }

        /* release session state, e.g. remove breakpoint instructions */
        dvmJdwpResetState(state);

        /* tell the interpreter that the debugger is no longer around */
        dvmDbgDisconnected();

        /* if we had threads suspended, resume them now */
        dvmUndoDebuggerSuspensions();

        /* if we connected out, this was a one-shot deal */
        if (!state->params.server)
            state->run = false;
    }

    /* back to running, for thread shutdown */
    dvmDbgThreadRunning();

    LOGV("JDWP: thread exiting\n");
    return NULL;
}


/*
 * Return the thread handle, or (pthread_t)0 if the debugger isn't running.
 */
pthread_t dvmJdwpGetDebugThread(JdwpState* state)
{
    if (state == NULL)
        return 0;

    return state->debugThreadHandle;
}

#if 0
/*
 * Wait until the debugger attaches.  Returns immediately if the debugger
 * is already attached.
 *
 * If we return the instant the debugger connects, we run the risk of
 * executing code before the debugger has had a chance to configure
 * breakpoints or issue suspend calls.  It would be nice to just sit in
 * the suspended state, but most debuggers don't expect any threads to be
 * suspended when they attach.
 *
 * There's no event we can post to tell the debugger "we've stopped, and
 * we like it that way".  We could send a fake breakpoint, which should
 * cause the debugger to immediately send a resume, but the debugger might
 * send the resume immediately or might throw an exception of its own upon
 * receiving a breakpoint event that it didn't ask for.
 *
 * What we really want is a "wait until the debugger is done configuring
 * stuff" event.  We can get close with a "wait until the debugger has
 * been idle for a brief period", and we can do a mild approximation with
 * "just sleep for a second after it connects".
 *
 * We should be in THREAD_VMWAIT here, so we're not allowed to do anything
 * with objects because a GC could be in progress.
 *
 * NOTE: this trips as soon as something connects to the socket.  This
 * is no longer appropriate -- we don't want to return when DDMS connects.
 * We could fix this by polling for the first debugger packet, but we have
 * to watch out for disconnects.  If we're going to do polling, it's
 * probably best to do it at a higher level.
 */
void dvmJdwpWaitForDebugger(JdwpState* state)
{
    // no more
}
#endif

/*
 * Get a notion of the current time, in milliseconds.  We leave it in
 * two 32-bit pieces.
 */
void dvmJdwpGetNowMsec(long* pSec, long* pMsec)
{
#ifdef HAVE_POSIX_CLOCKS
    struct timespec now;
    clock_gettime(CLOCK_MONOTONIC, &now);
    *pSec = now.tv_sec;
    *pMsec = now.tv_nsec / 1000000;
#else
    struct timeval now;
    gettimeofday(&now, NULL);
    *pSec = now.tv_sec;
    *pMsec = now.tv_usec / 1000;
#endif
}

/*
 * Return the time, in milliseconds, since the last debugger activity.
 *
 * Returns -1 if no debugger is attached, or 0 if we're in the middle of
 * processing a debugger request.
 */
s8 dvmJdwpLastDebuggerActivity(JdwpState* state)
{
    long lastSec, lastMsec;
    long nowSec, nowMsec;

    /* these are volatile; lastSec becomes 0 during update */
    lastSec = state->lastActivitySec;
    lastMsec = state->lastActivityMsec;

    /* initializing or in the middle of something? */
    if (lastSec == 0 || state->lastActivitySec != lastSec) {
        //LOGI("+++ last=busy\n");
        return 0;
    }

    /* get the current time *after* latching the "last" time */
    dvmJdwpGetNowMsec(&nowSec, &nowMsec);

    s8 last = (s8)lastSec * 1000 + lastMsec;
    s8 now = (s8)nowSec * 1000 + nowMsec;

    //LOGI("last is %ld.%ld --> %lld\n", lastSec, lastMsec, last);
    //LOGI("now is  %ld.%ld --> %lld\n", nowSec, nowMsec, now);


    //LOGI("+++ interval=%lld\n", now - last);
    return now - last;
}

