/*
Copyright (c) 2011, The Linux Foundation. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of The Linux Foundation nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <pthread.h>
#include "mm_camera_dbg.h"
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include "mm_camera_interface2.h"
#include "mm_camera.h"

typedef enum {
    /* ask the channel to flash out the queued frames. */
    MM_CAMERA_PIPE_CMD_FLASH_QUEUED_FRAME,
    /* ask ctrl fd to generate ch event to HAL */
    MM_CAMERA_PIPE_CMD_CH_EVENT,
    /*start*/
    MM_CAMERA_PIPE_CMD_ADD_CH,

    /*stop*/
    MM_CAMERA_PIPE_CMD_DEL_CH,

    /* exit */
    MM_CAMERA_PIPE_CMD_EXIT,
    /* max count */
    MM_CAMERA_PIPE_CMD_MAX
} mm_camera_pipe_cmd_type_t;

typedef enum {
    MM_CAMERA_POLL_TASK_STATE_POLL,     /* polling pid in polling state. */
    MM_CAMERA_POLL_TASK_STATE_MAX
} mm_camera_poll_task_state_type_t;

typedef struct {
    uint8_t cmd;
    mm_camera_event_t event;
} mm_camera_sig_evt_t;

static int32_t mm_camera_poll_sig(mm_camera_poll_thread_t *poll_cb,
                                  uint32_t cmd)
{
    /* send through pipe */
    /* get the mutex */
    mm_camera_sig_evt_t cmd_evt;
    memset(&cmd_evt, 0, sizeof(cmd_evt));
    cmd_evt.cmd = cmd;
    int len;
    CDBG("%s: begin", __func__);

    pthread_mutex_lock(&poll_cb->mutex);
    /* reset the statue to false */
    poll_cb->status = FALSE;
    /* send cmd to worker */
    len = write(poll_cb->data.pfds[1], &cmd_evt, sizeof(cmd_evt));
    if(len < 1) {
      CDBG("%s: len = %d, errno = %d", __func__, len, errno);
      //pthread_mutex_unlock(&poll_cb->mutex);
      //return -1;
    }
    CDBG("%s: begin IN mutex write done, len = %d", __func__, len);
    /* wait till worker task gives positive signal */
    while (!poll_cb->status) {
        int rc;
        struct timespec ts;
        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_sec += 2;
        CDBG("%s: wait", __func__);
        rc = pthread_cond_timedwait(&poll_cb->cond_v, &poll_cb->mutex, &ts);
        if (rc) {
            ALOGV("%s: error on pthread_cond_timedwait: %s", __func__, strerror(rc));
            break;
        }
    }
    /* done */
    pthread_mutex_unlock(&poll_cb->mutex);
    CDBG("%s: end, len = %d, size = %d", __func__, len, sizeof(cmd_evt));
    return MM_CAMERA_OK;
}

static void mm_camera_poll_sig_done(mm_camera_poll_thread_t *poll_cb)
{
    pthread_mutex_lock(&poll_cb->mutex);
    poll_cb->status = TRUE;
    pthread_cond_signal(&poll_cb->cond_v);
    CDBG("%s: done, in mutex", __func__);
    pthread_mutex_unlock(&poll_cb->mutex);
}

static int32_t mm_camera_poll_proc_msm(mm_camera_poll_thread_t *poll_cb, struct pollfd *fds)
{
   int i;

    for(i = 0; i < poll_cb->data.num_fds-1; i++) {
        /*Checking for data events*/
        if((poll_cb->data.poll_type == MM_CAMERA_POLL_TYPE_CH) &&
           (fds[i].revents & POLLIN) &&
           (fds[i].revents & POLLRDNORM)) {
            if(poll_cb->data.used) {
                mm_camera_msm_data_notify(poll_cb->data.my_obj,
                                        fds[i].fd,
                                        poll_cb->data.poll_streams[i]->stream_type);
            }

        }
        /*Checking for ctrl events*/
        if((poll_cb->data.poll_type == MM_CAMERA_POLL_TYPE_EVT) &&
           (fds[i].revents & POLLPRI)) {
          CDBG("%s: mm_camera_msm_evt_notify\n", __func__);
          mm_camera_msm_evt_notify(poll_cb->data.my_obj, fds[i].fd);
        }

    }
    return 0;
}

static void cm_camera_poll_set_state(mm_camera_poll_thread_t *poll_cb,
                                     mm_camera_poll_task_state_type_t state)
{
    poll_cb->data.state = state;
}

static void mm_camera_poll_proc_pipe(mm_camera_poll_thread_t *poll_cb)
{
    ssize_t read_len;
    int i;
    mm_camera_sig_evt_t cmd_evt;
    read_len = read(poll_cb->data.pfds[0], &cmd_evt, sizeof(cmd_evt));
    CDBG("%s: read_fd = %d, read_len = %d, expect_len = %d",
         __func__, poll_cb->data.pfds[0], (int)read_len, (int)sizeof(cmd_evt));
    switch(cmd_evt.cmd) {
    case MM_CAMERA_PIPE_CMD_FLASH_QUEUED_FRAME:
      mm_camera_dispatch_buffered_frames(poll_cb->data.my_obj,
                                         poll_cb->data.ch_type);
      break;
    case MM_CAMERA_PIPE_CMD_CH_EVENT: {
      mm_camera_event_t *event = &cmd_evt.event;
      CDBG("%s: ch event, type=0x%x, ch=%d, evt=%d",
           __func__, event->event_type, event->e.ch.ch, event->e.ch.evt);
      mm_camera_dispatch_app_event(poll_cb->data.my_obj, event);
      break;
    }
    case MM_CAMERA_PIPE_CMD_ADD_CH:
        if(poll_cb->data.poll_type == MM_CAMERA_POLL_TYPE_CH) {
            for(i = 0; i < MM_CAMERA_CH_STREAM_MAX; i++) {
                if(poll_cb->data.poll_streams[i]) {
                    poll_cb->data.poll_fd[poll_cb->data.num_fds + i] = poll_cb->data.poll_streams[i]->fd;
                }
            }
        }
        poll_cb->data.num_fds += mm_camera_ch_util_get_num_stream(poll_cb->data.my_obj,
                                                                      poll_cb->data.ch_type);
        poll_cb->data.used = 1;
        CDBG("Num fds after MM_CAMERA_PIPE_CMD_ADD_CH = %d",poll_cb->data.num_fds);
        break;

    case MM_CAMERA_PIPE_CMD_DEL_CH:
        poll_cb->data.num_fds -= mm_camera_ch_util_get_num_stream(poll_cb->data.my_obj,
                                                                  poll_cb->data.ch_type);
        poll_cb->data.used = 0;
        CDBG("Num fds after MM_CAMERA_PIPE_CMD_DEL_CH = %d",poll_cb->data.num_fds);
        break;

    case MM_CAMERA_PIPE_CMD_EXIT:
    default:
        cm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_MAX);
        mm_camera_poll_sig_done(poll_cb);
        break;
    }
}

static int mm_camera_poll_ch_busy(mm_camera_obj_t * my_obj, int ch_type)
{
    int i;
    int used = 0;
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
    pthread_mutex_lock(&poll_cb->mutex);
    used = poll_cb->data.used;
    pthread_mutex_unlock(&poll_cb->mutex);
    if(used)
        return 1;
    else
        return 0;
}
int32_t mm_camera_poll_dispatch_buffered_frames(mm_camera_obj_t * my_obj, int ch_type)
{
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
    mm_camera_sig_evt_t cmd;
    int len;

    cmd.cmd = MM_CAMERA_PIPE_CMD_FLASH_QUEUED_FRAME;
    memset(&cmd.event, 0, sizeof(cmd.event));
    pthread_mutex_lock(&poll_cb->mutex);
    len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
    pthread_mutex_unlock(&poll_cb->mutex);
    return MM_CAMERA_OK;
}

int mm_camera_poll_busy(mm_camera_obj_t * my_obj)
{
    int i;
    mm_camera_poll_thread_t *poll_cb;
    for(i = 0; i < (MM_CAMERA_POLL_THRAED_MAX - 1); i++) {
        if(mm_camera_poll_ch_busy(my_obj,  i) > 0)
          return 1;
    }
    return 0;
}

int mm_camera_poll_send_ch_event(mm_camera_obj_t * my_obj, mm_camera_event_t *event)
{
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[MM_CAMERA_CH_MAX];
    mm_camera_sig_evt_t cmd;
    int len;

    cmd.cmd = MM_CAMERA_PIPE_CMD_CH_EVENT;
    memcpy(&cmd.event, event, sizeof(cmd.event));
    CDBG("%s: ch event, type=0x%x, ch=%d, evt=%d, poll_type = %d, read_fd=%d, write_fd=%d",
        __func__, event->event_type, event->e.ch.ch, event->e.ch.evt, poll_cb->data.poll_type,
        poll_cb->data.pfds[0], poll_cb->data.pfds[1]);
    pthread_mutex_lock(&poll_cb->mutex);
    len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
    pthread_mutex_unlock(&poll_cb->mutex);
    return MM_CAMERA_OK;
}

static void *mm_camera_poll_fn(mm_camera_poll_thread_t *poll_cb)
{
    int rc = 0, i;
    struct pollfd fds[MM_CAMERA_CH_STREAM_MAX+1];
    int timeoutms;
    CDBG("%s: poll type = %d, num_fd = %d\n",
         __func__, poll_cb->data.poll_type, poll_cb->data.num_fds);
    do {
        for(i = 0; i < poll_cb->data.num_fds; i++) {
            fds[i].fd = poll_cb->data.poll_fd[i];
            fds[i].events = POLLIN|POLLRDNORM|POLLPRI;
        }
        timeoutms = poll_cb->data.timeoutms;
        rc = poll(fds, poll_cb->data.num_fds, timeoutms);
        if(rc > 0) {
            if((fds[0].revents & POLLIN) && (fds[0].revents & POLLRDNORM))
                mm_camera_poll_proc_pipe(poll_cb);
            else
                mm_camera_poll_proc_msm(poll_cb, &fds[1]);
        } else {
            /* in error case sleep 10 us and then continue. hard coded here */
            usleep(10);
            continue;
        }
    } while (poll_cb->data.state == MM_CAMERA_POLL_TASK_STATE_POLL);
    return NULL;
}

static void *mm_camera_poll_thread(void *data)
{
    int rc = 0;
    int i;
    void *ret = NULL;
    mm_camera_poll_thread_t *poll_cb = data;

    poll_cb->data.poll_fd[poll_cb->data.num_fds++] = poll_cb->data.pfds[0];
    switch(poll_cb->data.poll_type) {
    case MM_CAMERA_POLL_TYPE_EVT:
        poll_cb->data.poll_fd[poll_cb->data.num_fds++] =
          ((mm_camera_obj_t *)(poll_cb->data.my_obj))->ctrl_fd;
        break;
    case MM_CAMERA_POLL_TYPE_CH:
    default:
        break;
    }
    mm_camera_poll_sig_done(poll_cb);
    ret = mm_camera_poll_fn(poll_cb);
    return ret;
}

int mm_camera_poll_start(mm_camera_obj_t * my_obj,  mm_camera_poll_thread_t *poll_cb)
{
    pthread_mutex_lock(&poll_cb->mutex);
    poll_cb->status = 0;
    pthread_create(&poll_cb->data.pid, NULL, mm_camera_poll_thread, (void *)poll_cb);
    while (!poll_cb->status) {
        int rc;
        struct timespec ts;

        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_sec += 2;
        rc = pthread_cond_timedwait(&poll_cb->cond_v, &poll_cb->mutex, &ts);
        if (rc) {
            ALOGV("%s: error on pthread_cond_timedwait: %s", __func__, strerror(rc));
            break;
        }
    }
    pthread_mutex_unlock(&poll_cb->mutex);
    return MM_CAMERA_OK;
}

int mm_camera_poll_stop(mm_camera_obj_t * my_obj, mm_camera_poll_thread_t *poll_cb)
{
    CDBG("%s, my_obj=0x%x\n", __func__, (uint32_t)my_obj);
    mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_EXIT);
    if (pthread_join(poll_cb->data.pid, NULL) != 0) {
        CDBG("%s: pthread dead already\n", __func__);
    }
    return MM_CAMERA_OK;
}


int mm_camera_poll_thread_add_ch(mm_camera_obj_t * my_obj, int ch_type)
{
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
    mm_camera_sig_evt_t cmd;
    int len;

    if(poll_cb->data.used == 1){
        CDBG_ERROR("%s : Thread is Active",__func__);
        return MM_CAMERA_OK;
    }
    CDBG("Run thread for ch_type = %d ",ch_type);
    cmd.cmd = MM_CAMERA_PIPE_CMD_ADD_CH;
    poll_cb->data.ch_type = ch_type;

    pthread_mutex_lock(&poll_cb->mutex);
    len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
    pthread_mutex_unlock(&poll_cb->mutex);
    poll_cb->data.used = 1;
    return MM_CAMERA_OK;
}

int mm_camera_poll_thread_del_ch(mm_camera_obj_t * my_obj, int ch_type)
{
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
    mm_camera_sig_evt_t cmd;
    int len;

    if(poll_cb->data.used == 0){
        CDBG_ERROR("%s : Thread is Not Active",__func__);
        return MM_CAMERA_OK;
    }
    CDBG("Stop thread for ch_type = %d ",ch_type);
    cmd.cmd = MM_CAMERA_PIPE_CMD_DEL_CH;
    poll_cb->data.ch_type = (mm_camera_channel_type_t)ch_type;

    pthread_mutex_lock(&poll_cb->mutex);
    len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
    pthread_mutex_unlock(&poll_cb->mutex);
    poll_cb->data.used = 0;
    return MM_CAMERA_OK;

}


int mm_camera_poll_thread_launch(mm_camera_obj_t * my_obj, int ch_type)
{
    int rc = MM_CAMERA_OK;
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
    if(mm_camera_poll_ch_busy(my_obj, ch_type) > 0) {
        CDBG_ERROR("%s: err, poll thread of channel %d already running. cam_id=%d\n",
             __func__, ch_type, my_obj->my_id);
        return -MM_CAMERA_E_INVALID_OPERATION;
    }
    poll_cb->data.ch_type = ch_type;
    rc = pipe(poll_cb->data.pfds);
    if(rc < 0) {
        CDBG_ERROR("%s: camera_id = %d, pipe open rc=%d\n", __func__, my_obj->my_id, rc);
        rc = - MM_CAMERA_E_GENERAL;
    }
    CDBG("%s: ch = %d, poll_type = %d, read fd = %d, write fd = %d",
        __func__, ch_type, poll_cb->data.poll_type,
        poll_cb->data.pfds[0], poll_cb->data.pfds[1]);
    poll_cb->data.my_obj = my_obj;
    poll_cb->data.used = 0;
    poll_cb->data.timeoutms = -1;  /* Infinite seconds */

    if(ch_type < MM_CAMERA_CH_MAX) {
        poll_cb->data.poll_type = MM_CAMERA_POLL_TYPE_CH;
        mm_camera_ch_util_get_stream_objs(my_obj, ch_type,
                                      &poll_cb->data.poll_streams[0],
                                      &poll_cb->data.poll_streams[1]);
    } else{
        poll_cb->data.poll_type = MM_CAMERA_POLL_TYPE_EVT;
    }

    ALOGV("%s: ch_type = %d, poll_type = %d, read fd = %d, write fd = %d",
         __func__, ch_type, poll_cb->data.poll_type,
         poll_cb->data.pfds[0], poll_cb->data.pfds[1]);
    /* launch the thread */
    rc = mm_camera_poll_start(my_obj, poll_cb);
    return rc;
}

int mm_camera_poll_thread_release(mm_camera_obj_t * my_obj, int ch_type)
{
    int rc = MM_CAMERA_OK;
    mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
    if(MM_CAMERA_POLL_TASK_STATE_MAX == poll_cb->data.state) {
        CDBG("%s: err, poll thread of channel % is not running. cam_id=%d\n",
             __func__, ch_type, my_obj->my_id);
        return -MM_CAMERA_E_INVALID_OPERATION;
    }
    rc = mm_camera_poll_stop(my_obj, poll_cb);

    if(poll_cb->data.pfds[0]) {
        close(poll_cb->data.pfds[0]);
    }
    if(poll_cb->data.pfds[1]) {
        close(poll_cb->data.pfds[1]);
    }
    memset(&poll_cb->data, 0, sizeof(poll_cb->data));
    return MM_CAMERA_OK;
}

void mm_camera_poll_threads_init(mm_camera_obj_t * my_obj)
{
    int i;
    mm_camera_poll_thread_t *poll_cb;

    for(i = 0; i < MM_CAMERA_POLL_THRAED_MAX; i++) {
        poll_cb = &my_obj->poll_threads[i];
        pthread_mutex_init(&poll_cb->mutex, NULL);
        pthread_cond_init(&poll_cb->cond_v, NULL);
    }
}

void mm_camera_poll_threads_deinit(mm_camera_obj_t * my_obj)
{
    int i;
    mm_camera_poll_thread_t *poll_cb;

    for(i = 0; i < MM_CAMERA_POLL_THRAED_MAX; i++) {
        poll_cb = &my_obj->poll_threads[i];
        if(poll_cb->data.used)
            mm_camera_poll_stop(my_obj, poll_cb);
        pthread_mutex_destroy(&poll_cb->mutex);
        pthread_cond_destroy(&poll_cb->cond_v);
        memset(poll_cb, 0, sizeof(mm_camera_poll_thread_t));
    }
}
