/*
 * Copyright (C) 2010 The Android Open Source Project
 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * Not a Contribution, Apache license notifications and license are
 * retained for attribution purposes only.

 * 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 <cutils/properties.h>
#include <utils/Log.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/msm_mdp.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <poll.h>
#include "hwc_utils.h"
#include "hdmi.h"
#include "qd_utils.h"
#include "string.h"
#include "overlay.h"
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>

using namespace qdutils;
namespace qhwc {

#define HWC_VSYNC_THREAD_NAME "hwcVsyncThread"
#define PANEL_ON_STR "panel_power_on ="
#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
#define MAX_THERMAL_LEVEL 3
const int MAX_DATA = 64;

int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)
{
    int ret = 0;
    if(!ctx->vstate.fakevsync &&
       ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
             &enable) < 0) {
        ALOGE("%s: vsync control failed. Dpy=%d, enable=%d : %s",
              __FUNCTION__, dpy, enable, strerror(errno));
        ret = -errno;
    }
    return ret;
}

static void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data)
{
    // extract timestamp
    uint64_t timestamp = 0;
    if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
        timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
    }
    // send timestamp to SurfaceFlinger
    ALOGD_IF (ctx->vstate.debug, "%s: timestamp %" PRIu64" sent to SF for dpy=%d",
            __FUNCTION__, timestamp, dpy);
    ctx->proc->vsync(ctx->proc, dpy, timestamp);
}

static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data)
{
    if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) {
        unsigned long int poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
        ALOGI("%s: dpy:%d panel power state: %ld", __FUNCTION__, dpy, poweron);
        if (!ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
            ctx->dpyAttr[dpy].isActive = poweron ? true: false;
        }
    }
}

static void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data)
{
    // extract thermal level
    uint64_t thermalLevel = 0;
    if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) {
        thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0);
    }

    if (thermalLevel >= MAX_THERMAL_LEVEL) {
        ALOGD("%s: dpy:%d thermal_level=%" PRIu64"",__FUNCTION__,dpy,thermalLevel);
        ctx->mThermalBurstMode = true;
    } else
        ctx->mThermalBurstMode = false;
}

struct event {
    const char* name;
    void (*callback)(hwc_context_t* ctx, int dpy, char *data);
};

struct event event_list[] =  {
    { "vsync_event", handle_vsync_event },
    { "show_blank_event", handle_blank_event },
    { "msm_fb_thermal_level", handle_thermal_event },
};

#define num_events ARRAY_LENGTH(event_list)

static void *vsync_loop(void *param)
{
    hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);

    char thread_name[64] = HWC_VSYNC_THREAD_NAME;
    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY +
                android::PRIORITY_MORE_FAVORABLE);

    char vdata[MAX_DATA];
    //Number of physical displays
    //We poll on all the nodes.
    int num_displays = HWC_NUM_DISPLAY_TYPES - 1;
    struct pollfd pfd[num_displays][num_events];

    char property[PROPERTY_VALUE_MAX];
    if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
        if(atoi(property) == 1)
            ctx->vstate.fakevsync = true;
    }

    char node_path[MAX_SYSFS_FILE_PATH];

    for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
        for(size_t ev = 0; ev < num_events; ev++) {
            snprintf(node_path, sizeof(node_path),
                    "/sys/class/graphics/fb%d/%s",
                    dpy == HWC_DISPLAY_PRIMARY ? 0 :
                    overlay::Overlay::getInstance()->
                    getFbForDpy(HWC_DISPLAY_EXTERNAL),
                    event_list[ev].name);

            ALOGI("%s: Reading event %zu for dpy %d from %s", __FUNCTION__,
                    ev, dpy, node_path);
            pfd[dpy][ev].fd = open(node_path, O_RDONLY);

            if (dpy == HWC_DISPLAY_PRIMARY && pfd[dpy][ev].fd < 0) {
                // Make sure fb device is opened before starting
                // this thread so this never happens.
                ALOGE ("%s:unable to open event node for dpy=%d event=%zu, %s",
                        __FUNCTION__, dpy, ev, strerror(errno));
                if (ev == 0) {
                    ctx->vstate.fakevsync = true;
                    //XXX: Blank events don't work with fake vsync,
                    //but we shouldn't be running on fake vsync anyway.
                    break;
                }
            }

            pread(pfd[dpy][ev].fd, vdata , MAX_DATA, 0);
            if (pfd[dpy][ev].fd >= 0)
                pfd[dpy][ev].events = POLLPRI | POLLERR;
        }
    }

    if (LIKELY(!ctx->vstate.fakevsync)) {
        do {
            int err = poll(*pfd, (int)(num_displays * num_events), -1);
            if(err > 0) {
                for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
                    for(size_t ev = 0; ev < num_events; ev++) {
                        if (pfd[dpy][ev].revents & POLLPRI) {
                            ssize_t len = pread(pfd[dpy][ev].fd, vdata, MAX_DATA, 0);
                            if (UNLIKELY(len < 0)) {
                                // If the read was just interrupted - it is not
                                // a fatal error. Just continue in this case
                                ALOGE ("%s: Unable to read event:%zu for \
                                        dpy=%d : %s",
                                        __FUNCTION__, ev, dpy, strerror(errno));
                                continue;
                            }
                            event_list[ev].callback(ctx, dpy, vdata);
                        }
                    }
                }
            } else {
                ALOGE("%s: poll failed errno: %s", __FUNCTION__,
                        strerror(errno));
                continue;
            }
        } while (true);

    } else {

        //Fake vsync is used only when set explicitly through a property or when
        //the vsync timestamp node cannot be opened at bootup. There is no
        //fallback to fake vsync from the true vsync loop, ever, as the
        //condition can easily escape detection.
        //Also, fake vsync is delivered only for the primary display.
        do {
            usleep(16666);
            uint64_t timestamp = systemTime();
            ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);

        } while (true);
    }

    for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) {
        for( size_t event = 0; event < num_events; event++) {
            if(pfd[dpy][event].fd >= 0)
                close (pfd[dpy][event].fd);
        }
    }

    return NULL;
}

void init_vsync_thread(hwc_context_t* ctx)
{
    int ret;
    pthread_t vsync_thread;
    ALOGI("Initializing VSYNC Thread");
    ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
    if (ret) {
        ALOGE("%s: failed to create %s: %s", __FUNCTION__,
              HWC_VSYNC_THREAD_NAME, strerror(ret));
    }
}

}; //namespace
