/*
 * Copyright (C) 2012 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 <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

#include <log/log.h>
#include <hardware/hwcomposer.h>
#include <sync/sync.h>

struct ranchu_hwc_composer_device_1 {
    hwc_composer_device_1_t base; // constant after init
    const hwc_procs_t *procs;     // constant after init
    pthread_t vsync_thread;       // constant after init
    int32_t vsync_period_ns;      // constant after init
    framebuffer_device_t* fbdev;  // constant after init

    pthread_mutex_t vsync_lock;
    bool vsync_callback_enabled; // protected by this->vsync_lock
};

static int hwc_prepare(hwc_composer_device_1_t* dev __unused,
                       size_t numDisplays, hwc_display_contents_1_t** displays) {

    if (!numDisplays || !displays) return 0;

    hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];

    if (!contents) return 0;

    for (size_t i = 0; i < contents->numHwLayers; i++) {
    // We do not handle any layers, so set composition type of any non
    // HWC_FRAMEBUFFER_TARGET layer to to HWC_FRAMEBUFFER.
        if (contents->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
            continue;
        }
        contents->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
    }
    return 0;
}

static int hwc_set(struct hwc_composer_device_1* dev,size_t numDisplays,
                   hwc_display_contents_1_t** displays) {
    struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev;
    if (!numDisplays || !displays) {
        return 0;
    }

    hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];

    int retireFenceFd = -1;
    int err = 0;
    for (size_t layer = 0; layer < contents->numHwLayers; layer++) {
            hwc_layer_1_t* fb_layer = &contents->hwLayers[layer];

        int releaseFenceFd = -1;
        if (fb_layer->acquireFenceFd > 0) {
            const int kAcquireWarningMS= 3000;
            err = sync_wait(fb_layer->acquireFenceFd, kAcquireWarningMS);
            if (err < 0 && errno == ETIME) {
                ALOGE("hwcomposer waited on fence %d for %d ms",
                      fb_layer->acquireFenceFd, kAcquireWarningMS);
            }
            close(fb_layer->acquireFenceFd);

            if (fb_layer->compositionType != HWC_FRAMEBUFFER_TARGET) {
                ALOGE("hwcomposer found acquire fence on layer %d which is not an"
                      "HWC_FRAMEBUFFER_TARGET layer", layer);
            }

            releaseFenceFd = dup(fb_layer->acquireFenceFd);
            fb_layer->acquireFenceFd = -1;
        }

        if (fb_layer->compositionType != HWC_FRAMEBUFFER_TARGET) {
            continue;
        }

        pdev->fbdev->post(pdev->fbdev, fb_layer->handle);
        fb_layer->releaseFenceFd = releaseFenceFd;

        if (releaseFenceFd > 0) {
            if (retireFenceFd == -1) {
                retireFenceFd = dup(releaseFenceFd);
            } else {
                int mergedFenceFd = sync_merge("hwc_set retireFence",
                                               releaseFenceFd, retireFenceFd);
                close(retireFenceFd);
                retireFenceFd = mergedFenceFd;
            }
        }
    }

    contents->retireFenceFd = retireFenceFd;
    return err;
}

static int hwc_query(struct hwc_composer_device_1* dev, int what, int* value) {
    struct ranchu_hwc_composer_device_1* pdev =
            (struct ranchu_hwc_composer_device_1*)dev;

    switch (what) {
        case HWC_BACKGROUND_LAYER_SUPPORTED:
            // we do not support the background layer
            value[0] = 0;
            break;
        case HWC_VSYNC_PERIOD:
            value[0] = pdev->vsync_period_ns;
            break;
        default:
            // unsupported query
            ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what);
            return -EINVAL;
    }
    return 0;
}

static int hwc_event_control(struct hwc_composer_device_1* dev, int dpy __unused,
                             int event, int enabled) {
    struct ranchu_hwc_composer_device_1* pdev =
            (struct ranchu_hwc_composer_device_1*)dev;
    int ret = -EINVAL;

    // enabled can only be 0 or 1
    if (!(enabled & ~1)) {
        if (event == HWC_EVENT_VSYNC) {
            pthread_mutex_lock(&pdev->vsync_lock);
            pdev->vsync_callback_enabled=enabled;
            pthread_mutex_unlock(&pdev->vsync_lock);
            ret = 0;
        }
    }
    return ret;
}

static int hwc_blank(struct hwc_composer_device_1* dev __unused, int disp,
                     int blank __unused) {
    if (disp != HWC_DISPLAY_PRIMARY) {
        return -EINVAL;
    }
    return 0;
}

static void hwc_dump(hwc_composer_device_1* dev __unused, char* buff __unused,
                     int buff_len __unused) {
    // This is run when running dumpsys.
    // No-op for now.
}


static int hwc_get_display_configs(struct hwc_composer_device_1* dev __unused,
                                   int disp, uint32_t* configs, size_t* numConfigs) {
    if (*numConfigs == 0) {
        return 0;
    }

    if (disp == HWC_DISPLAY_PRIMARY) {
        configs[0] = 0;
        *numConfigs = 1;
        return 0;
    }

    return -EINVAL;
}


static int32_t hwc_attribute(struct ranchu_hwc_composer_device_1* pdev,
                             const uint32_t attribute) {
    switch(attribute) {
        case HWC_DISPLAY_VSYNC_PERIOD:
            return pdev->vsync_period_ns;
        case HWC_DISPLAY_WIDTH:
            return pdev->fbdev->width;
        case HWC_DISPLAY_HEIGHT:
            return pdev->fbdev->height;
        case HWC_DISPLAY_DPI_X:
            return pdev->fbdev->xdpi*1000;
        case HWC_DISPLAY_DPI_Y:
            return pdev->fbdev->ydpi*1000;
        default:
            ALOGE("unknown display attribute %u", attribute);
            return -EINVAL;
    }
}

static int hwc_get_display_attributes(struct hwc_composer_device_1* dev __unused,
                                      int disp, uint32_t config __unused,
                                      const uint32_t* attributes, int32_t* values) {

    struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev;
    for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
        if (disp == HWC_DISPLAY_PRIMARY) {
            values[i] = hwc_attribute(pdev, attributes[i]);
        } else {
            ALOGE("unknown display type %u", disp);
            return -EINVAL;
        }
    }

    return 0;
}

static int hwc_close(hw_device_t* dev) {
    struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev;
    pthread_kill(pdev->vsync_thread, SIGTERM);
    pthread_join(pdev->vsync_thread, NULL);
    free(dev);
    return 0;
}

static void* hwc_vsync_thread(void* data) {
    struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)data;
    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);

    struct timespec rt;
    if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
        ALOGE("%s:%d error in vsync thread clock_gettime: %s",
              __FILE__, __LINE__, strerror(errno));
    }
    const int log_interval = 60;
    int64_t last_logged = rt.tv_sec;
    int sent = 0;
    int last_sent = 0;
    bool vsync_enabled = false;
    struct timespec wait_time;
    wait_time.tv_sec = 0;
    wait_time.tv_nsec = pdev->vsync_period_ns;

    while (true) {
        int err = nanosleep(&wait_time, NULL);
        if (err == -1) {
            if (errno == EINTR) {
                break;
            }
            ALOGE("error in vsync thread: %s", strerror(errno));
        }

        pthread_mutex_lock(&pdev->vsync_lock);
        vsync_enabled = pdev->vsync_callback_enabled;
        pthread_mutex_unlock(&pdev->vsync_lock);

        if (!vsync_enabled) {
            continue;
        }

        if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
            ALOGE("%s:%d error in vsync thread clock_gettime: %s",
                  __FILE__, __LINE__, strerror(errno));
        }

        int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
        pdev->procs->vsync(pdev->procs, 0, timestamp);
        if (rt.tv_sec - last_logged >= log_interval) {
            ALOGD("hw_composer sent %d syncs in %ds", sent - last_sent, rt.tv_sec - last_logged);
            last_logged = rt.tv_sec;
            last_sent = sent;
        }
        ++sent;
    }

    return NULL;
}

static void hwc_register_procs(struct hwc_composer_device_1* dev,
                               hwc_procs_t const* procs) {
    struct ranchu_hwc_composer_device_1* pdev = (struct ranchu_hwc_composer_device_1*)dev;
    pdev->procs = procs;
}

static int hwc_open(const struct hw_module_t* module, const char* name,
                    struct hw_device_t** device) {
    int ret = 0;

    if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
        ALOGE("%s called with bad name %s", __FUNCTION__, name);
        return -EINVAL;
    }

    ranchu_hwc_composer_device_1 *pdev = new ranchu_hwc_composer_device_1();
    if (!pdev) {
        ALOGE("%s failed to allocate dev", __FUNCTION__);
        return -ENOMEM;
    }

    pdev->base.common.tag = HARDWARE_DEVICE_TAG;
    pdev->base.common.version = HWC_DEVICE_API_VERSION_1_1;
    pdev->base.common.module = const_cast<hw_module_t *>(module);
    pdev->base.common.close = hwc_close;

    pdev->base.prepare = hwc_prepare;
    pdev->base.set = hwc_set;
    pdev->base.eventControl = hwc_event_control;
    pdev->base.blank = hwc_blank;
    pdev->base.query = hwc_query;
    pdev->base.registerProcs = hwc_register_procs;
    pdev->base.dump = hwc_dump;
    pdev->base.getDisplayConfigs = hwc_get_display_configs;
    pdev->base.getDisplayAttributes = hwc_get_display_attributes;

    pdev->vsync_period_ns = 1000*1000*1000/60; // vsync is 60 hz

    hw_module_t const* hw_module;
    ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module);
    if (ret != 0) {
        ALOGE("ranchu_hw_composer hwc_open %s module not found", GRALLOC_HARDWARE_MODULE_ID);
        return ret;
    }
    ret = framebuffer_open(hw_module, &pdev->fbdev);
    if (ret != 0) {
        ALOGE("ranchu_hw_composer hwc_open could not open framebuffer");
    }

    pthread_mutex_init(&pdev->vsync_lock, NULL);
    pdev->vsync_callback_enabled = false;

    ret = pthread_create (&pdev->vsync_thread, NULL, hwc_vsync_thread, pdev);
    if (ret) {
        ALOGE("ranchu_hw_composer could not start vsync_thread\n");
    }

    *device = &pdev->base.common;

    return ret;
}


static struct hw_module_methods_t hwc_module_methods = {
    open: hwc_open,
};

hwc_module_t HAL_MODULE_INFO_SYM = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        module_api_version: HWC_MODULE_API_VERSION_0_1,
        hal_api_version: HARDWARE_HAL_API_VERSION,
        id: HWC_HARDWARE_MODULE_ID,
        name: "Android Emulator hwcomposer module",
        author: "The Android Open Source Project",
        methods: &hwc_module_methods,
    }
};
