/*
 * Copyright (C) 2009 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.
 */

/* this program is used to read a set of system properties and their values
 * from the emulator program and set them in the currently-running emulated
 * system. It does so by connecting to the 'boot-properties' qemud service.
 *
 * This program should be run as root and called from
 * /system/etc/init.goldfish.rc exclusively.
 */

#define LOG_TAG  "qemu-props"

#define DEBUG  1

#if DEBUG
#  include <log/log.h>
#  define  DD(...)    ALOGI(__VA_ARGS__)
#else
#  define  DD(...)    ((void)0)
#endif

#include <cutils/properties.h>
#include <unistd.h>
#include "qemud.h"

/* Name of the qemud service we want to connect to.
 */
#define  QEMUD_SERVICE  "boot-properties"

#define  MAX_TRIES      5

#define QEMU_MISC_PIPE "QemuMiscPipe"

int s_QemuMiscPipe = -1;
void static notifyHostBootComplete();
void static sendHeartBeat();
void static sendMessage(const char* mesg);

int  main(void)
{
    int  qemud_fd, count = 0;

    /* try to connect to the qemud service */
    {
        int  tries = MAX_TRIES;

        while (1) {
            qemud_fd = qemud_channel_open( "boot-properties" );
            if (qemud_fd >= 0)
                break;

            if (--tries <= 0) {
                DD("Could not connect after too many tries. Aborting");
                return 1;
            }

            DD("waiting 1s to wait for qemud.");
            sleep(1);
        }
    }

    DD("connected to '%s' qemud service.", QEMUD_SERVICE);

    /* send the 'list' command to the service */
    if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
        DD("could not send command to '%s' service", QEMUD_SERVICE);
        return 1;
    }

    /* read each system property as a single line from the service,
     * until exhaustion.
     */
    for (;;)
    {
#define  BUFF_SIZE   (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
        DD("receiving..");
        char* q;
        char  temp[BUFF_SIZE];
        char  vendortemp[BUFF_SIZE];
        int   len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);

        /* lone NUL-byte signals end of properties */
        if (len < 0 || len > BUFF_SIZE-1 || temp[0] == '\0')
            break;

        temp[len] = '\0';  /* zero-terminate string */

        DD("received: %.*s", len, temp);

        /* separate propery name from value */
        q = strchr(temp, '=');
        if (q == NULL) {
            DD("invalid format, ignored.");
            continue;
        }
        *q++ = '\0';

        char* final_prop_name = NULL;
        if (strcmp(temp, "qemu.sf.lcd.density") == 0 ) {
            final_prop_name = temp;
        } else if (strcmp(temp, "qemu.hw.mainkeys") == 0 ) {
            final_prop_name = temp;
        } else if (strcmp(temp, "qemu.cmdline") == 0 ) {
            final_prop_name = temp;
        } else if (strcmp(temp, "dalvik.vm.heapsize") == 0 ) {
            continue; /* cannot set it here */
        } else if (strcmp(temp, "ro.opengles.version") == 0 ) {
            continue; /* cannot set it here */
        } else {
            snprintf(vendortemp, sizeof(vendortemp), "vendor.%s", temp);
            final_prop_name = vendortemp;
        }
        if (property_set(temp, q) < 0) {
            ALOGW("could not set property '%s' to '%s'", final_prop_name, q);
        } else {
            ALOGI("successfully set property '%s' to '%s'", final_prop_name, q);
            count += 1;
        }
    }

    close(qemud_fd);

    char temp[BUFF_SIZE];
    sendHeartBeat();
    while (s_QemuMiscPipe >= 0) {
        usleep(5000000); /* 5 seconds */
        sendHeartBeat();
        property_get("vendor.qemu.dev.bootcomplete", temp, "");
        int is_boot_completed = (strncmp(temp, "1", 1) == 0) ? 1 : 0;
        if (is_boot_completed) {
            ALOGI("tell the host boot completed");
            notifyHostBootComplete();
            break;
        }
    }

    while (s_QemuMiscPipe >= 0) {
        usleep(30*1000000); /* 30 seconds */
        sendHeartBeat();
    }

    /* finally, close the channel and exit */
    if (s_QemuMiscPipe >= 0) {
        close(s_QemuMiscPipe);
        s_QemuMiscPipe = -1;
    }
    DD("exiting (%d properties set).", count);
    return 0;
}

void sendHeartBeat() {
    sendMessage("heartbeat");
}

void notifyHostBootComplete() {
    sendMessage("bootcomplete");
}

void sendMessage(const char* mesg) {
   if (s_QemuMiscPipe < 0) {
        s_QemuMiscPipe = qemu_pipe_open(QEMU_MISC_PIPE);
        if (s_QemuMiscPipe < 0) {
            ALOGE("failed to open %s", QEMU_MISC_PIPE);
            return;
        }
    }
    char set[64];
    snprintf(set, sizeof(set), "%s", mesg);
    int pipe_command_length = strlen(set)+1; //including trailing '\0'
    WriteFully(s_QemuMiscPipe, &pipe_command_length, sizeof(pipe_command_length));
    WriteFully(s_QemuMiscPipe, set, pipe_command_length);
    ReadFully(s_QemuMiscPipe, &pipe_command_length, sizeof(pipe_command_length));
    if (pipe_command_length > (int)(sizeof(set)) || pipe_command_length <= 0)
        return;
    ReadFully(s_QemuMiscPipe, set, pipe_command_length);
}
