/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/* the following is needed on Linux to define ptsname() in stdlib.h */
#if defined(__linux__)
#define _GNU_SOURCE 1
#endif

#ifndef _WIN32
#include <sys/wait.h>
#endif  // _WIN32

#ifdef _WIN32
#include <windows.h>
#include <sys/timeb.h>
#endif

#include "qemu-common.h"
#include "net/net.h"
#include "ui/console.h"
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "block/block.h"
#include "android/sockets.h"
#include "audio/audio.h"

#include "android/android.h"
#include "android/charpipe.h"
#include "android/globals.h"
#include "android/utils/bufprint.h"
#include "android/utils/system.h"
#include "android/protocol/core-connection.h"
#include "android/protocol/attach-ui-impl.h"
#include "android/protocol/fb-updates-impl.h"
#include "android/protocol/user-events-proxy.h"
#include "android/protocol/core-commands-proxy.h"
#include "android/protocol/ui-commands-impl.h"
#include "android/qemulator.h"

static Looper*  mainLooper;

/***********************************************************/
/* I/O handling */

typedef struct IOHandlerRecord {
    LoopIo  io[1];
    IOHandler* fd_read;
    IOHandler* fd_write;
    int        running;
    int        deleted;
    void*      opaque;
    struct IOHandlerRecord *next;
} IOHandlerRecord;

static IOHandlerRecord *first_io_handler;

static void ioh_callback(void* opaque, int fd, unsigned events)
{
    IOHandlerRecord* ioh = opaque;
    ioh->running = 1;
    if ((events & LOOP_IO_READ) != 0) {
        ioh->fd_read(ioh->opaque);
    }
    if (!ioh->deleted && (events & LOOP_IO_WRITE) != 0) {
        ioh->fd_write(ioh->opaque);
    }
    ioh->running = 0;
    if (ioh->deleted) {
        loopIo_done(ioh->io);
        free(ioh);
    }
}

int qemu_set_fd_handler(int fd,
                        IOHandler *fd_read,
                        IOHandler *fd_write,
                        void *opaque)
{
    IOHandlerRecord **pioh, *ioh;

    if (!fd_read && !fd_write) {
        pioh = &first_io_handler;
        for(;;) {
            ioh = *pioh;
            if (ioh == NULL)
                return 0;
            if (ioh->io->fd == fd) {
                break;
            }
            pioh = &ioh->next;
        }
        if (ioh->running) {
            ioh->deleted = 1;
        } else {
            *pioh = ioh->next;
            loopIo_done(ioh->io);
            free(ioh);
        }
    } else {
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
            if (ioh->io->fd == fd)
                goto found;
        }
        ANEW0(ioh);
        ioh->next = first_io_handler;
        first_io_handler = ioh;
        loopIo_init(ioh->io, mainLooper, fd, ioh_callback, ioh);
    found:
        ioh->fd_read  = fd_read;
        ioh->fd_write = fd_write;
        ioh->opaque   = opaque;

        if (fd_read != NULL)
            loopIo_wantRead(ioh->io);
        else
            loopIo_dontWantRead(ioh->io);

        if (fd_write != NULL)
            loopIo_wantWrite(ioh->io);
        else
            loopIo_dontWantWrite(ioh->io);
    }
    return 0;
}

/***********************************************************/
/* main execution loop */

static LoopTimer  gui_timer[1];

static void gui_update(void *opaque)
{
    LoopTimer* timer = opaque;
    qframebuffer_pulse();
    loopTimer_startRelative(timer, GUI_REFRESH_INTERVAL);
}

static void init_gui_timer(Looper* looper)
{
    loopTimer_init(gui_timer, looper, gui_update, gui_timer);
    loopTimer_startRelative(gui_timer, 0);
    qframebuffer_invalidate_all();
}

/* Called from qemulator.c */
void qemu_system_shutdown_request(void)
{
    looper_forceQuit(mainLooper);
}

#ifndef _WIN32

static void termsig_handler(int signal)
{
    qemu_system_shutdown_request();
}

static void sigchld_handler(int signal)
{
    waitpid(-1, NULL, WNOHANG);
}

static void sighandler_setup(void)
{
    struct sigaction act;

    memset(&act, 0, sizeof(act));
    act.sa_handler = termsig_handler;
    sigaction(SIGINT,  &act, NULL);
    sigaction(SIGHUP,  &act, NULL);
    sigaction(SIGTERM, &act, NULL);

    act.sa_handler = sigchld_handler;
    act.sa_flags = SA_NOCLDSTOP;
    sigaction(SIGCHLD, &act, NULL);
}

#endif

#ifdef _WIN32
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
{
    exit(STATUS_CONTROL_C_EXIT);
    return TRUE;
}
#endif

int qemu_main(int argc, char **argv, char **envp)
{
#ifndef _WIN32
    {
        struct sigaction act;
        sigfillset(&act.sa_mask);
        act.sa_flags = 0;
        act.sa_handler = SIG_IGN;
        sigaction(SIGPIPE, &act, NULL);
    }
#else
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
       QEMU to run on a single CPU */
    {
        HANDLE h;
        DWORD mask, smask;
        int i;
        h = GetCurrentProcess();
        if (GetProcessAffinityMask(h, &mask, &smask)) {
            for(i = 0; i < 32; i++) {
                if (mask & (1 << i))
                    break;
            }
            if (i != 32) {
                mask = 1 << i;
                SetProcessAffinityMask(h, mask);
            }
        }
    }
#endif

#ifdef _WIN32
    socket_init();
#endif

#ifndef _WIN32
    /* must be after terminal init, SDL library changes signal handlers */
    sighandler_setup();
#endif

    mainLooper = looper_newGeneric();

    /* Register a timer to call qframebuffer_pulse periodically */
    init_gui_timer(mainLooper);

    // Connect to the core's framebuffer service
    if (fbUpdatesImpl_create(attachUiImpl_get_console_socket(), "-raw",
                             qemulator_get_first_framebuffer(qemulator_get()),
                             mainLooper)) {
        return -1;
    }

    // Attach the recepient of UI commands.
    if (uiCmdImpl_create(attachUiImpl_get_console_socket(), mainLooper)) {
        return -1;
    }

    looper_run(mainLooper);

    fbUpdatesImpl_destroy();
    userEventsProxy_destroy();
    coreCmdProxy_destroy();
    uiCmdImpl_destroy();
    attachUiImpl_destroy();

    return 0;
}
