// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>

#include <unordered_map>

#include <base/bind.h>
#include <base/logging.h>
#include <base/threading/thread.h>

#include "common/libcab_test_internal.h"
#include "cros-camera/camera_algorithm.h"
#include "cros-camera/common.h"
#include "cros-camera/future.h"

namespace libcab_test {

class CameraAlgorithmImpl {
 public:
  static CameraAlgorithmImpl* GetInstance() {
    static CameraAlgorithmImpl impl;
    return &impl;
  }

  int32_t Initialize(const camera_algorithm_callback_ops_t* callback_ops) {
    if (!callback_ops) {
      return -EINVAL;
    }
    callback_ops_ = callback_ops;
    return 0;
  }

  int32_t RegisterBuffer(int buffer_fd) {
    if (handles_.find(buffer_fd) != handles_.end()) {
      LOGF(ERROR) << "Buffer already registered";
      return -EINVAL;
    }
    struct stat sb;
    if (fstat(buffer_fd, &sb) == -1) {
      LOGF(ERROR) << "Failed to get buffer status";
      return -EBADFD;
    }
    void* addr = mmap(0, sb.st_size, PROT_WRITE, MAP_SHARED, buffer_fd, 0);
    if (!addr) {
      LOGF(ERROR) << "Failed to map buffer";
      return -EBADFD;
    }
    int32_t handle = -1;
    static unsigned int seed = time(NULL) + getpid();
    do {
      handle = rand_r(&seed);
    } while (shm_info_map_.find(handle) != shm_info_map_.end());
    handles_[buffer_fd] = handle;
    shm_info_map_[handle].fd = buffer_fd;
    shm_info_map_[handle].addr = addr;
    shm_info_map_[handle].size = sb.st_size;
    return handle;
  }

  void Request(uint32_t req_id,
               const uint8_t req_header[],
               uint32_t size,
               int32_t buffer_handle) {
    uint32_t status = 0;
    switch (req_header[0]) {
      case REQUEST_TEST_COMMAND_NORMAL:
        if (shm_info_map_.find(buffer_handle) == shm_info_map_.end()) {
          LOGF(ERROR) << "Invalid buffer handle";
          status = -EBADF;
        }
        break;
      case REQUEST_TEST_COMMAND_VERIFY_STATUS:
        status = SimpleHash(req_header, size);
        break;
      case REQUEST_TEST_COMMAND_DEAD_LOCK:
        base::PlatformThread::Sleep(base::TimeDelta::Max());
        break;
      default:
        status = -EINVAL;
    }
    thread_.task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&CameraAlgorithmImpl::ReturnCallback, base::Unretained(this),
                   req_id, status, buffer_handle));
  }

  void DeregisterBuffers(const int32_t buffer_handles[], uint32_t size) {
    for (uint32_t i = 0; i < size; i++) {
      if (shm_info_map_.find(buffer_handles[i]) == shm_info_map_.end()) {
        LOGF(ERROR) << "Invalid buffer handle (" << buffer_handles[i] << ")";
        continue;
      }
      handles_.erase(shm_info_map_[buffer_handles[i]].fd);
      munmap(shm_info_map_[buffer_handles[i]].addr,
             shm_info_map_[buffer_handles[i]].size);
      close(shm_info_map_[buffer_handles[i]].fd);
      shm_info_map_.erase(buffer_handles[i]);
    }
  }

 private:
  CameraAlgorithmImpl()
      : thread_("Camera Algorithm Thread"), callback_ops_(nullptr) {
    thread_.Start();
  }

  void ReturnCallback(uint32_t req_id, uint32_t status, int32_t buffer_handle) {
    (*callback_ops_->return_callback)(callback_ops_, req_id, status,
                                      buffer_handle);
  }

  base::Thread thread_;

  const camera_algorithm_callback_ops_t* callback_ops_;

  typedef struct {
    int32_t fd;
    void* addr;
    size_t size;
  } ShmInfo;

  // Store shared memory fd and mapped address with handle as the key
  std::unordered_map<int32_t, ShmInfo> shm_info_map_;

  // Store handles with fd as the key
  std::unordered_map<int32_t, int32_t> handles_;
};

static int32_t Initialize(const camera_algorithm_callback_ops_t* callback_ops) {
  return CameraAlgorithmImpl::GetInstance()->Initialize(callback_ops);
}

static int32_t RegisterBuffer(int32_t buffer_fd) {
  return CameraAlgorithmImpl::GetInstance()->RegisterBuffer(buffer_fd);
}

static void Request(uint32_t req_id,
                    const uint8_t req_header[],
                    uint32_t size,
                    int32_t buffer_handle) {
  CameraAlgorithmImpl::GetInstance()->Request(req_id, req_header, size,
                                              buffer_handle);
}

static void DeregisterBuffers(const int32_t buffer_handles[], uint32_t size) {
  CameraAlgorithmImpl::GetInstance()->DeregisterBuffers(buffer_handles, size);
}

}  // namespace libcab_test

extern "C" {
camera_algorithm_ops_t CAMERA_ALGORITHM_MODULE_INFO_SYM
    __attribute__((__visibility__("default"))) = {
        .initialize = libcab_test::Initialize,
        .register_buffer = libcab_test::RegisterBuffer,
        .request = libcab_test::Request,
        .deregister_buffers = libcab_test::DeregisterBuffers};
}
