/*
 * Copyright (C) 2018 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 "TouchVideoDevice.h"

#define LOG_TAG "TouchVideoDevice"

#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <iostream>

#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <log/log.h>

using android::base::StringPrintf;
using android::base::unique_fd;

namespace android {

TouchVideoDevice::TouchVideoDevice(int fd, std::string&& name, std::string&& devicePath,
                                   uint32_t height, uint32_t width,
                                   const std::array<const int16_t*, NUM_BUFFERS>& readLocations)
      : mFd(fd),
        mName(std::move(name)),
        mPath(std::move(devicePath)),
        mHeight(height),
        mWidth(width),
        mReadLocations(readLocations) {
    mFrames.reserve(MAX_QUEUE_SIZE);
};

std::unique_ptr<TouchVideoDevice> TouchVideoDevice::create(std::string devicePath) {
    unique_fd fd(open(devicePath.c_str(), O_RDWR | O_NONBLOCK));
    if (fd.get() == INVALID_FD) {
        ALOGE("Could not open video device %s: %s", devicePath.c_str(), strerror(errno));
        return nullptr;
    }

    struct v4l2_capability cap;
    int result = ioctl(fd.get(), VIDIOC_QUERYCAP, &cap);
    if (result == -1) {
        ALOGE("VIDIOC_QUERYCAP failed: %s", strerror(errno));
        return nullptr;
    }
    if (!(cap.capabilities & V4L2_CAP_TOUCH)) {
        ALOGE("Capability V4L2_CAP_TOUCH is not present, can't use device for heatmap data. "
              "Make sure device specifies V4L2_CAP_TOUCH");
        return nullptr;
    }
    ALOGI("Opening video device: driver = %s, card = %s, bus_info = %s, version = %i", cap.driver,
          cap.card, cap.bus_info, cap.version);
    std::string name = reinterpret_cast<const char*>(cap.card);

    struct v4l2_input v4l2_input_struct;
    v4l2_input_struct.index = 0;
    result = ioctl(fd.get(), VIDIOC_ENUMINPUT, &v4l2_input_struct);
    if (result == -1) {
        ALOGE("VIDIOC_ENUMINPUT failed: %s", strerror(errno));
        return nullptr;
    }

    if (v4l2_input_struct.type != V4L2_INPUT_TYPE_TOUCH) {
        ALOGE("Video device does not provide touch data. "
              "Make sure device specifies V4L2_INPUT_TYPE_TOUCH.");
        return nullptr;
    }

    struct v4l2_format v4l2_fmt;
    v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    result = ioctl(fd.get(), VIDIOC_G_FMT, &v4l2_fmt);
    if (result == -1) {
        ALOGE("VIDIOC_G_FMT failed: %s", strerror(errno));
        return nullptr;
    }
    const uint32_t height = v4l2_fmt.fmt.pix.height;
    const uint32_t width = v4l2_fmt.fmt.pix.width;
    ALOGI("Frame dimensions: height = %" PRIu32 " width = %" PRIu32, height, width);

    struct v4l2_requestbuffers req = {};
    req.count = NUM_BUFFERS;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
    // req.reserved is zeroed during initialization, which is required per v4l docs
    result = ioctl(fd.get(), VIDIOC_REQBUFS, &req);
    if (result == -1) {
        ALOGE("VIDIOC_REQBUFS failed: %s", strerror(errno));
        return nullptr;
    }
    if (req.count != NUM_BUFFERS) {
        ALOGE("Requested %zu buffers, but driver responded with count=%i", NUM_BUFFERS, req.count);
        return nullptr;
    }

    struct v4l2_buffer buf = {};
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    // buf.reserved and buf.reserved2 are zeroed during initialization, required per v4l docs
    std::array<const int16_t*, NUM_BUFFERS> readLocations;
    for (size_t i = 0; i < NUM_BUFFERS; i++) {
        buf.index = i;
        result = ioctl(fd.get(), VIDIOC_QUERYBUF, &buf);
        if (result == -1) {
            ALOGE("VIDIOC_QUERYBUF failed: %s", strerror(errno));
            return nullptr;
        }
        if (buf.length != height * width * sizeof(int16_t)) {
            ALOGE("Unexpected value of buf.length = %i (offset = %" PRIu32 ")", buf.length,
                  buf.m.offset);
            return nullptr;
        }

        readLocations[i] = static_cast<const int16_t*>(
                mmap(nullptr /* start anywhere */, buf.length, PROT_READ /* required */,
                     MAP_SHARED /* recommended */, fd.get(), buf.m.offset));
        if (readLocations[i] == MAP_FAILED) {
            ALOGE("%s: map failed: %s", __func__, strerror(errno));
            return nullptr;
        }
    }

    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    result = ioctl(fd.get(), VIDIOC_STREAMON, &type);
    if (result == -1) {
        ALOGE("VIDIOC_STREAMON failed: %s", strerror(errno));
        return nullptr;
    }

    for (size_t i = 0; i < NUM_BUFFERS; i++) {
        buf.index = i;
        result = ioctl(fd.get(), VIDIOC_QBUF, &buf);
        if (result == -1) {
            ALOGE("VIDIOC_QBUF failed for buffer %zu: %s", i, strerror(errno));
            return nullptr;
        }
    }
    // Using 'new' to access a non-public constructor.
    return std::unique_ptr<TouchVideoDevice>(new TouchVideoDevice(fd.release(), std::move(name),
                                                                  std::move(devicePath), height,
                                                                  width, readLocations));
}

size_t TouchVideoDevice::readAndQueueFrames() {
    std::vector<TouchVideoFrame> frames = readFrames();
    const size_t numFrames = frames.size();
    if (numFrames == 0) {
        // Likely an error occurred
        return 0;
    }
    // Concatenate the vectors, then clip up to maximum size allowed
    mFrames.insert(mFrames.end(), std::make_move_iterator(frames.begin()),
                   std::make_move_iterator(frames.end()));
    if (mFrames.size() > MAX_QUEUE_SIZE) {
        // A user-space grip suppression process may be processing the video frames, and holding
        // back the input events. This could result in video frames being produced without the
        // matching input events. Drop the oldest frame here to prepare for the next input event.
        mFrames.erase(mFrames.begin(), mFrames.end() - MAX_QUEUE_SIZE);
    }
    return numFrames;
}

std::vector<TouchVideoFrame> TouchVideoDevice::consumeFrames() {
    std::vector<TouchVideoFrame> frames = std::move(mFrames);
    mFrames = {};
    return frames;
}

std::optional<TouchVideoFrame> TouchVideoDevice::readFrame() {
    struct v4l2_buffer buf = {};
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
    int result = ioctl(mFd.get(), VIDIOC_DQBUF, &buf);
    if (result == -1) {
        // EAGAIN means we've reached the end of the read buffer, so it's expected.
        if (errno != EAGAIN) {
            ALOGE("VIDIOC_DQBUF failed: %s", strerror(errno));
        }
        return std::nullopt;
    }
    if ((buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) != V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
        // We use CLOCK_MONOTONIC for input events, so if the clocks don't match,
        // we can't compare timestamps. Just log a warning, since this is a driver issue
        ALOGW("The timestamp %ld.%ld was not acquired using CLOCK_MONOTONIC", buf.timestamp.tv_sec,
              buf.timestamp.tv_usec);
    }
    std::vector<int16_t> data(mHeight * mWidth);
    const int16_t* readFrom = mReadLocations[buf.index];
    std::copy(readFrom, readFrom + mHeight * mWidth, data.begin());
    TouchVideoFrame frame(mHeight, mWidth, std::move(data), buf.timestamp);

    result = ioctl(mFd.get(), VIDIOC_QBUF, &buf);
    if (result == -1) {
        ALOGE("VIDIOC_QBUF failed: %s", strerror(errno));
    }
    return std::make_optional(std::move(frame));
}

/*
 * This function should not be called unless buffer is ready! This must be checked with
 * select, poll, epoll, or some other similar api first.
 * The oldest frame will be at the beginning of the array.
 */
std::vector<TouchVideoFrame> TouchVideoDevice::readFrames() {
    std::vector<TouchVideoFrame> frames;
    while (true) {
        std::optional<TouchVideoFrame> frame = readFrame();
        if (!frame) {
            break;
        }
        frames.push_back(std::move(*frame));
    }
    return frames;
}

TouchVideoDevice::~TouchVideoDevice() {
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    int result = ioctl(mFd.get(), VIDIOC_STREAMOFF, &type);
    if (result == -1) {
        ALOGE("VIDIOC_STREAMOFF failed: %s", strerror(errno));
    }
    for (const int16_t* buffer : mReadLocations) {
        void* bufferAddress = static_cast<void*>(const_cast<int16_t*>(buffer));
        result = munmap(bufferAddress, mHeight * mWidth * sizeof(int16_t));
        if (result == -1) {
            ALOGE("%s: Couldn't unmap: [%s]", __func__, strerror(errno));
        }
    }
}

std::string TouchVideoDevice::dump() const {
    return StringPrintf("Video device %s (%s) : height=%" PRIu32 ", width=%" PRIu32
                        ", fd=%i, hasValidFd=%s",
                        mName.c_str(), mPath.c_str(), mHeight, mWidth, mFd.get(),
                        hasValidFd() ? "true" : "false");
}

} // namespace android
