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

#include <map>

#include <v8.h>
#include "ril.h"


#include "hardware/ril/mock-ril/src/proto/ril.pb.h"

#include "logging.h"
#include "js_support.h"
#include "mock_ril.h"
#include "node_buffer.h"
#include "node_object_wrap.h"
#include "node_util.h"
#include "protobuf_v8.h"
#include "status.h"
#include "util.h"
#include "worker.h"

#include "requests.h"

//#define REQUESTS_DEBUG
#ifdef  REQUESTS_DEBUG

#define DBG(...) ALOGD(__VA_ARGS__)

#else

#define DBG(...)

#endif


/**
 * Request has no data so create an empty Buffer
 */
int ReqWithNoData(Buffer **pBuffer,
        const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    static Buffer *emptyBuffer = Buffer::New(0L);

    DBG("ReqWithNoData E");
    *pBuffer = emptyBuffer;
    status = STATUS_OK;

    DBG("ReqWithNoData X status=%d", status);
    return status;
}

/**
 * request for RIL_REQUEST_ENTER_SIM_PIN  // 2
 */
int ReqEnterSimPin(Buffer **pBuffer,
        const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    Buffer *buffer;

    DBG("ReqEnterSimPin E");
    if (datalen < sizeof(int)) {
        ALOGE("ReqEnterSimPin: data to small err size < sizeof int");
        status = STATUS_BAD_DATA;
    } else {
        ril_proto::ReqEnterSimPin *req = new ril_proto::ReqEnterSimPin();
        DBG("ReqEnterSimPin: pin = %s", ((const char **)data)[0]);
        req->set_pin((((char **)data)[0]));
        buffer = Buffer::New(req->ByteSize());
        req->SerializeToArray(buffer->data(), buffer->length());
        delete req;
        *pBuffer = buffer;
        status = STATUS_OK;
    }
    DBG("ReqEnterSimPin X status=%d", status);
    return status;
}

/**
 * request for RIL_REQUEST_DIAL  // 10
 */
int ReqDial(Buffer **pBuffer,
            const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    Buffer *buffer;

    DBG("ReqDial E");
    DBG("data=%p datalen=%d t=%p", data, datalen, t);

    if (datalen < sizeof(int)) {
        ALOGE("ReqDial: data to small err size < sizeof int");
        status = STATUS_BAD_DATA;
    } else {
        ril_proto::ReqDial *req = new ril_proto::ReqDial();

        // cast the data to RIL_Dial
        RIL_Dial *rilDial = (RIL_Dial *)data;
        DBG("ReqDial: rilDial->address =%s, rilDial->clir=%d", rilDial->address, rilDial->clir);

        req->set_address(rilDial->address);
        req->set_clir(rilDial->clir);
        ril_proto::RilUusInfo *uusInfo = (ril_proto::RilUusInfo *)(&(req->uus_info()));

        if (rilDial->uusInfo != NULL) {
            DBG("ReqDial: print uusInfo:");
            DBG("rilDial->uusInfo->uusType = %d, "
                "rilDial->uusInfo->uusDcs =%d, "
                "rilDial->uusInfo->uusLength=%d, "
                "rilDial->uusInfo->uusData = %s",
                rilDial->uusInfo->uusType,
                rilDial->uusInfo->uusDcs,
                rilDial->uusInfo->uusLength,
                rilDial->uusInfo->uusData);

            uusInfo->set_uus_type((ril_proto::RilUusType)rilDial->uusInfo->uusType);
            uusInfo->set_uus_dcs((ril_proto::RilUusDcs)rilDial->uusInfo->uusDcs);
            uusInfo->set_uus_length(rilDial->uusInfo->uusLength);
            uusInfo->set_uus_data(rilDial->uusInfo->uusData);
        } else {
            DBG("uusInfo is NULL");
        }

        DBG("ReqDial: after set the request");
        DBG("req->ByetSize=%d", req->ByteSize());
        buffer = Buffer::New(req->ByteSize());
        DBG("buffer size=%d", buffer->length());

        req->SerializeToArray(buffer->data(), buffer->length());
        delete req;
        *pBuffer = buffer;
        status = STATUS_OK;
        DBG("ReqDial X, buffer->length()=%d", buffer->length());
    }
    DBG("ReqDial X status = %d", status);
    return status;
}

/**
 * request for RIL_REQUEST_HANGUP    // 12
 */
int ReqHangUp(Buffer **pBuffer,
        const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    Buffer *buffer;

    DBG("ReqHangUp E");
    if (datalen < sizeof(int)) {
        ALOGE("ReqHangUp: data to small err size < sizeof int");
        status = STATUS_BAD_DATA;
    } else {
        ril_proto::ReqHangUp *req = new ril_proto::ReqHangUp();
        DBG("ReqHangUp: connection_index=%d", ((int *)data)[0]);
        req->set_connection_index(((int *)data)[0]);
        buffer = Buffer::New(req->ByteSize());
        req->SerializeToArray(buffer->data(), buffer->length());
        delete req;
        *pBuffer = buffer;
        status = STATUS_OK;
    }
    DBG("ReqHangUp X status=%d", status);
    return status;
}

/**
 * request for RIL_REQUEST_SEPARATE_CONNECTION    // 52
 */
int ReqSeparateConnection (Buffer **pBuffer,
                           const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    Buffer *buffer;
    v8::HandleScope handle_scope;

    DBG("ReqSeparateConnection E");
    if (datalen < sizeof(int)) {
        ALOGE("ReqSetMute: data to small err size < sizeof int");
        status = STATUS_BAD_DATA;
    } else {
        ril_proto::ReqSeparateConnection *req = new ril_proto::ReqSeparateConnection();
        DBG("ReqSeparateConnection: index=%d", ((int *)data)[0]);
        req->set_index(((int *)data)[0]);
        DBG("ReqSeparateConnection: req->ByetSize=%d", req->ByteSize());
        buffer = Buffer::New(req->ByteSize());
        req->SerializeToArray(buffer->data(), buffer->length());
        delete req;
        *pBuffer = buffer;
        status = STATUS_OK;
    }
    DBG("ReqSeparateConnection X status=%d", status);
    return status;
}

/**
 * request for RIL_REQUEST_SET_MUTE      // 53
 */
int ReqSetMute(Buffer **pBuffer,
               const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    Buffer *buffer;
    v8::HandleScope handle_scope;

    DBG("ReqSetMute E");
    if (datalen < sizeof(int)) {
        ALOGE("ReqSetMute: data to small err size < sizeof int");
        status = STATUS_BAD_DATA;
    } else {
        ril_proto::ReqSetMute *req = new ril_proto::ReqSetMute();
        DBG("ReqSetMute: state=%d", ((int *)data)[0]);
        req->set_state(((int *)data)[0]);
        DBG("ReqSetMute: req->ByetSize=%d", req->ByteSize());
        buffer = Buffer::New(req->ByteSize());
        req->SerializeToArray(buffer->data(), buffer->length());
        delete req;
        *pBuffer = buffer;
        status = STATUS_OK;
    }
    DBG("ReqSetMute X status=%d", status);
    return status;
}

/**
 * request for RIL_REQUEST_SCREEN_STATE  // 61
 */
int ReqScreenState(Buffer **pBuffer,
        const void *data, const size_t datalen, const RIL_Token t) {
    int status;
    Buffer *buffer;
    v8::HandleScope handle_scope;

    DBG("ReqScreenState E data=%p datalen=%d t=%p",
         data, datalen, t);
    if (datalen < sizeof(int)) {
        ALOGE("ReqScreenState: data to small err size < sizeof int");
        status = STATUS_BAD_DATA;
    } else {
        ril_proto::ReqScreenState *req = new ril_proto::ReqScreenState();
        DBG("ReqScreenState: state=%d", ((int *)data)[0]);
        req->set_state(((int *)data)[0]);
        DBG("ReqScreenState: req->ByteSize()=%d", req->ByteSize());
        buffer = Buffer::New(req->ByteSize());
        DBG("ReqScreenState: serialize");
        req->SerializeToArray(buffer->data(), buffer->length());
        delete req;
        *pBuffer = buffer;
        status = STATUS_OK;
    }
    DBG("ReqScreenState X status=%d", status);
    return status;
}

/**
 * Map from indexed by cmd and used to convert Data to Protobuf.
 */
typedef int (*ReqConversion)(Buffer** pBuffer, const void *data,
                const size_t datalen, const RIL_Token t);
typedef std::map<int, ReqConversion> ReqConversionMap;
ReqConversionMap rilReqConversionMap;

int callOnRilRequest(v8::Handle<v8::Context> context, int cmd,
                   const void *buffer, RIL_Token t) {
    DBG("callOnRilRequest E: cmd=%d", cmd);

    int status;
    v8::HandleScope handle_scope;
    v8::TryCatch try_catch;

    // Get the onRilRequest Function
    v8::Handle<v8::String> name = v8::String::New("onRilRequest");
    v8::Handle<v8::Value> onRilRequestFunctionValue = context->Global()->Get(name);
    v8::Handle<v8::Function> onRilRequestFunction =
        v8::Handle<v8::Function>::Cast(onRilRequestFunctionValue);

    // Create the cmd and token
    v8::Handle<v8::Value> v8RequestValue = v8::Number::New(cmd);
    v8::Handle<v8::Value> v8TokenValue = v8::Number::New(int64_t(t));

    // Invoke onRilRequest
    const int argc = 3;
    v8::Handle<v8::Value> argv[argc] = {
            v8RequestValue, v8TokenValue, ((Buffer *)buffer)->handle_ };
    v8::Handle<v8::Value> result =
        onRilRequestFunction->Call(context->Global(), argc, argv);
    if (try_catch.HasCaught()) {
        ALOGE("callOnRilRequest error");
        ReportException(&try_catch);
        status = STATUS_ERR;
    } else {
        v8::String::Utf8Value result_string(result);
        DBG("callOnRilRequest result=%s", ToCString(result_string));
        status = STATUS_OK;
    }

    DBG("callOnRilRequest X: status=%d", status);
    return status;
}

RilRequestWorkerQueue::RilRequestWorkerQueue(v8::Handle<v8::Context> context) {
    DBG("RilRequestWorkerQueue E:");

    context_ = context;
    pthread_mutex_init(&free_list_mutex_, NULL);

    DBG("RilRequestWorkerQueue X:");
}

RilRequestWorkerQueue::~RilRequestWorkerQueue() {
    DBG("~RilRequestWorkerQueue E:");
    Request *req;
    pthread_mutex_lock(&free_list_mutex_);
    while(free_list_.size() != 0) {
        req = free_list_.front();
        delete req;
        free_list_.pop();
    }
    pthread_mutex_unlock(&free_list_mutex_);
    pthread_mutex_destroy(&free_list_mutex_);
    DBG("~RilRequestWorkerQueue X:");
}

/**
 * Add a request to the processing queue.
 * Data is serialized to a protobuf before adding to the queue.
 */
void RilRequestWorkerQueue::AddRequest (const int request,
        const void *data, const size_t datalen, const RIL_Token token) {
    DBG("RilRequestWorkerQueue:AddRequest: %d E", request);

    v8::Locker locker;
    v8::HandleScope handle_scope;
    v8::Context::Scope context_scope(context_);

    int status;

    // Convert the data to a protobuf before inserting it into the request queue (serialize data)
    Buffer *buffer = NULL;
    ReqConversionMap::iterator itr;
    itr = rilReqConversionMap.find(request);
    if (itr != rilReqConversionMap.end()) {
        status = itr->second(&buffer, data, datalen, token);
    } else {
        ALOGE("RilRequestWorkerQueue:AddRequest: X unknown request %d", request);
        status = STATUS_UNSUPPORTED_REQUEST;
    }

    if (status == STATUS_OK) {
        // Add serialized request to the queue
        Request *req;
        pthread_mutex_lock(&free_list_mutex_);
        DBG("RilRequestWorkerQueue:AddRequest: return ok, buffer = %p, buffer->length()=%d",
            buffer, buffer->length());
        if (free_list_.size() == 0) {
            req = new Request(request, buffer, token);
            pthread_mutex_unlock(&free_list_mutex_);
        } else {
            req = free_list_.front();
            free_list_.pop();
            pthread_mutex_unlock(&free_list_mutex_);
            req->Set(request, buffer, token);
        }
        // add the request
        Add(req);
    } else {
        DBG("RilRequestWorkerQueue:AddRequest: return from the serialization, status is not OK");
        // An error report complete now
        RIL_Errno rilErrCode = (status == STATUS_UNSUPPORTED_REQUEST) ?
                 RIL_E_REQUEST_NOT_SUPPORTED : RIL_E_GENERIC_FAILURE;
        s_rilenv->OnRequestComplete(token, rilErrCode, NULL, 0);
    }

    DBG("RilRequestWorkerQueue::AddRequest: X"
         " request=%d data=%p datalen=%d token=%p",
            request, data, datalen, token);
}

void RilRequestWorkerQueue::Process(void *p) {

    Request *req = (Request *)p;
    DBG("RilRequestWorkerQueue::Process: E"
         " request=%d buffer=%p, bufferlen=%d t=%p",
            req->request_, req->buffer_, req->buffer_->length(), req->token_);

    v8::Locker locker;
    v8::HandleScope handle_scope;
    v8::Context::Scope context_scope(context_);
    callOnRilRequest(context_, req->request_,
                          req->buffer_, req->token_);

    pthread_mutex_lock(&free_list_mutex_);
    free_list_.push(req);
    pthread_mutex_unlock(&free_list_mutex_);
}

int requestsInit(v8::Handle<v8::Context> context, RilRequestWorkerQueue **rwq) {
    ALOGD("requestsInit E");

    rilReqConversionMap[RIL_REQUEST_GET_SIM_STATUS] = ReqWithNoData; // 1
    rilReqConversionMap[RIL_REQUEST_ENTER_SIM_PIN] = ReqEnterSimPin; // 2
    rilReqConversionMap[RIL_REQUEST_GET_CURRENT_CALLS] = ReqWithNoData; // 9
    rilReqConversionMap[RIL_REQUEST_DIAL] = ReqDial;   // 10
    rilReqConversionMap[RIL_REQUEST_GET_IMSI] = ReqWithNoData; // 11
    rilReqConversionMap[RIL_REQUEST_HANGUP] = ReqHangUp; // 12
    rilReqConversionMap[RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND] = ReqWithNoData; // 13
    rilReqConversionMap[RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = ReqWithNoData; // 14
    rilReqConversionMap[RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = ReqWithNoData; // 15
    rilReqConversionMap[RIL_REQUEST_CONFERENCE] = ReqWithNoData;  // 16
    rilReqConversionMap[RIL_REQUEST_LAST_CALL_FAIL_CAUSE] = ReqWithNoData;  // 18
    rilReqConversionMap[RIL_REQUEST_SIGNAL_STRENGTH] = ReqWithNoData; // 19
    rilReqConversionMap[RIL_REQUEST_VOICE_REGISTRATION_STATE] = ReqWithNoData; // 20
    rilReqConversionMap[RIL_REQUEST_DATA_REGISTRATION_STATE] = ReqWithNoData; // 21
    rilReqConversionMap[RIL_REQUEST_OPERATOR] = ReqWithNoData; // 22
    rilReqConversionMap[RIL_REQUEST_GET_IMEI] = ReqWithNoData; // 38
    rilReqConversionMap[RIL_REQUEST_GET_IMEISV] = ReqWithNoData; // 39
    rilReqConversionMap[RIL_REQUEST_ANSWER] = ReqWithNoData; // 40
    rilReqConversionMap[RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE] = ReqWithNoData; // 45
    rilReqConversionMap[RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC] = ReqWithNoData; // 46
    rilReqConversionMap[RIL_REQUEST_BASEBAND_VERSION] = ReqWithNoData; // 51
    rilReqConversionMap[RIL_REQUEST_SEPARATE_CONNECTION] = ReqSeparateConnection; // 52
    rilReqConversionMap[RIL_REQUEST_SET_MUTE] = ReqSetMute; // 53
    rilReqConversionMap[RIL_REQUEST_SCREEN_STATE] = ReqScreenState; // 61

    *rwq = new RilRequestWorkerQueue(context);
    int status = (*rwq)->Run();

    ALOGD("requestsInit X: status=%d", status);
    return status;
}

/**
 * Subroutine to test a single RIL request
 */
void testRilRequest(v8::Handle<v8::Context> context, int request, const void *data,
                    const size_t datalen, const RIL_Token t) {
    Buffer *buffer = NULL;
    ReqConversionMap::iterator itr;
    int status;

    ALOGD("testRilRequest: request=%d", request);

    itr = rilReqConversionMap.find(request);
    if (itr != rilReqConversionMap.end()) {
        status = itr->second(&buffer, data, sizeof(data), (void *)0x12345677);
    } else {
        ALOGE("testRequests X unknown request %d", request);
        status = STATUS_UNSUPPORTED_REQUEST;
    }
    if (status == STATUS_OK) {
        callOnRilRequest(context, request, buffer, (void *)0x12345677);
    } else {
        ALOGE("testRilRequest X, serialize error");
    }
}

void testRequests(v8::Handle<v8::Context> context) {
    ALOGD("testRequests E: ********");

    v8::TryCatch try_catch;

    char *buffer;
    const char *fileName= "/sdcard/data/mock_ril.js";
    int status = ReadFile(fileName, &buffer);
    if (status == 0) {
        runJs(context, &try_catch, fileName, buffer);
        Buffer *buffer = NULL;
        ReqConversionMap::iterator itr;
        int status;
        int request;

        if (!try_catch.HasCaught()) {
            {
                const int data[1] = { 1 };
                testRilRequest(context, RIL_REQUEST_SIGNAL_STRENGTH, data, sizeof(data),
                               (void *)0x12345677);
            }
            {
                const char *data[1] = { "winks-pin" };
                testRilRequest(context, RIL_REQUEST_ENTER_SIM_PIN, data, sizeof(data),
                               (void *)0x12345677);
            }
            {
                const int data[1] = { 1 };
                testRilRequest(context, RIL_REQUEST_HANGUP, data, sizeof(data),
                               (void *)0x12345677);
            }
            {
                const int data[1] = { 1 };
                testRilRequest(context, RIL_REQUEST_SCREEN_STATE, data, sizeof(data),
                               (void *)0x12345677);
            }
            {
                const int data[1] = { 1 };
                testRilRequest(context, RIL_REQUEST_GET_SIM_STATUS, data, sizeof(data),
                               (void *)0x12345677);
            }
            {
                RilRequestWorkerQueue *rwq = new RilRequestWorkerQueue(context);
                if (rwq->Run() == STATUS_OK) {
                    const int data[1] = { 1 };
                    rwq->AddRequest(RIL_REQUEST_SCREEN_STATE,
                                    data, sizeof(data), (void *)0x1234567A);
                    rwq->AddRequest(RIL_REQUEST_SIGNAL_STRENGTH,
                                    data, sizeof(data), (void *)0x1234567A);
                    // Sleep to let it be processed
                    v8::Unlocker unlocker;
                    sleep(3);
                    v8::Locker locker;
                }
                delete rwq;
            }
        }
    }

    ALOGD("testRequests X: ********\n");
}
