/*
 * 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 "common/camera_algorithm_bridge_impl.h"

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <mojo/public/cpp/system/platform_handle.h>

#include "cros-camera/common.h"
#include "cros-camera/constants.h"

namespace cros {

// static
std::unique_ptr<CameraAlgorithmBridge> CameraAlgorithmBridge::CreateInstance(
    CameraAlgorithmBackend backend) {
  return CameraAlgorithmBridge::CreateInstance(
      backend, CameraMojoChannelManager::GetInstance());
}

// static
std::unique_ptr<CameraAlgorithmBridge> CameraAlgorithmBridge::CreateInstance(
    CameraAlgorithmBackend backend, CameraMojoChannelManager* mojo_manager) {
  VLOGF_ENTER();
  return std::make_unique<CameraAlgorithmBridgeImpl>(backend, mojo_manager);
}

CameraAlgorithmBridgeImpl::CameraAlgorithmBridgeImpl(
    CameraAlgorithmBackend backend, CameraMojoChannelManager* mojo_manager)
    : mojo_manager_(mojo_manager),
      ipc_bridge_(new IPCBridge(backend, mojo_manager)) {}

CameraAlgorithmBridgeImpl::~CameraAlgorithmBridgeImpl() {
  VLOGF_ENTER();

  bool result = mojo_manager_->GetIpcTaskRunner()->DeleteSoon(
      FROM_HERE, std::move(ipc_bridge_));
  DCHECK(result);

  VLOGF_EXIT();
}

int32_t CameraAlgorithmBridgeImpl::Initialize(
    const camera_algorithm_callback_ops_t* callback_ops) {
  VLOGF_ENTER();

  const int32_t kInitializationRetryTimeoutMs = 3000;
  const int32_t kInitializationWaitConnectionMs = 500;
  const int32_t kInitializationRetrySleepUs = 100000;
  auto get_elapsed_ms = [](struct timespec& start) {
    struct timespec stop = {};
    if (clock_gettime(CLOCK_MONOTONIC, &stop)) {
      LOG(ERROR) << "Failed to get clock time";
      return 0L;
    }
    return (stop.tv_sec - start.tv_sec) * 1000 +
           (stop.tv_nsec - start.tv_nsec) / 1000000;
  };
  struct timespec start_ts = {};
  if (clock_gettime(CLOCK_MONOTONIC, &start_ts)) {
    LOG(ERROR) << "Failed to get clock time";
  }
  int ret = 0;
  do {
    int32_t elapsed_ms = get_elapsed_ms(start_ts);
    if (elapsed_ms >= kInitializationRetryTimeoutMs) {
      ret = -ETIMEDOUT;
      break;
    }
    auto future = cros::Future<int32_t>::Create(&relay_);

    mojo_manager_->GetIpcTaskRunner()->PostTask(
        FROM_HERE, base::Bind(&CameraAlgorithmBridgeImpl::IPCBridge::Initialize,
                              ipc_bridge_->GetWeakPtr(), callback_ops,
                              cros::GetFutureCallback(future)));

    if (future->Wait(std::min(kInitializationWaitConnectionMs,
                              kInitializationRetryTimeoutMs - elapsed_ms))) {
      ret = future->Get();
      if (ret == 0 || ret == -EINVAL) {
        break;
      }
    }
    usleep(kInitializationRetrySleepUs);
  } while (1);
  VLOGF_EXIT();
  return ret;
}

int32_t CameraAlgorithmBridgeImpl::RegisterBuffer(int buffer_fd) {
  VLOGF_ENTER();
  auto future = cros::Future<int32_t>::Create(&relay_);

  mojo_manager_->GetIpcTaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(&CameraAlgorithmBridgeImpl::IPCBridge::RegisterBuffer,
                 ipc_bridge_->GetWeakPtr(), buffer_fd,
                 cros::GetFutureCallback(future)));

  future->Wait();
  VLOGF_EXIT();
  return future->Get();
}

void CameraAlgorithmBridgeImpl::Request(uint32_t req_id,
                                        const std::vector<uint8_t>& req_header,
                                        int32_t buffer_handle) {
  VLOGF_ENTER();

  mojo_manager_->GetIpcTaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(&CameraAlgorithmBridgeImpl::IPCBridge::Request,
                 ipc_bridge_->GetWeakPtr(), req_id, req_header, buffer_handle));

  VLOGF_EXIT();
}

void CameraAlgorithmBridgeImpl::DeregisterBuffers(
    const std::vector<int32_t>& buffer_handles) {
  VLOGF_ENTER();

  mojo_manager_->GetIpcTaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(&CameraAlgorithmBridgeImpl::IPCBridge::DeregisterBuffers,
                 ipc_bridge_->GetWeakPtr(), buffer_handles));

  VLOGF_EXIT();
}

CameraAlgorithmBridgeImpl::IPCBridge::IPCBridge(
    CameraAlgorithmBackend backend, CameraMojoChannelManager* mojo_manager)
    : algo_backend_(backend),
      callback_ops_(nullptr),
      mojo_manager_(mojo_manager),
      ipc_task_runner_(mojo_manager_->GetIpcTaskRunner()) {}

CameraAlgorithmBridgeImpl::IPCBridge::~IPCBridge() {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  VLOGF_ENTER();

  Destroy();
}

void CameraAlgorithmBridgeImpl::IPCBridge::Initialize(
    const camera_algorithm_callback_ops_t* callback_ops,
    base::Callback<void(int32_t)> cb) {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  VLOGF_ENTER();
  if (!callback_ops || !callback_ops->return_callback) {
    cb.Run(-EINVAL);
    return;
  }
  if (cb_impl_) {
    LOGF(WARNING)
        << "Camera algorithm bridge is already initialized. Reinitializing...";
    Destroy();
  }

  constexpr char kGpuAlgoJobFilePath[] = "/etc/init/cros-camera-gpu-algo.conf";
  switch (algo_backend_) {
    case CameraAlgorithmBackend::kVendorCpu:
      interface_ptr_ = mojo_manager_->CreateCameraAlgorithmOpsPtr(
          cros::constants::kCrosCameraAlgoSocketPathString, "vendor_cpu");
      break;
    case CameraAlgorithmBackend::kVendorGpu:
      if (!base::PathExists(base::FilePath(kGpuAlgoJobFilePath))) {
        cb.Run(-EINVAL);
        return;
      }
      interface_ptr_ = mojo_manager_->CreateCameraAlgorithmOpsPtr(
          cros::constants::kCrosCameraGPUAlgoSocketPathString, "vendor_gpu");
      break;
    case CameraAlgorithmBackend::kGoogleGpu:
      if (!base::PathExists(base::FilePath(kGpuAlgoJobFilePath))) {
        cb.Run(-EINVAL);
        return;
      }
      interface_ptr_ = mojo_manager_->CreateCameraAlgorithmOpsPtr(
          cros::constants::kCrosCameraGPUAlgoSocketPathString, "google_gpu");
      break;
    case CameraAlgorithmBackend::kTest:
      interface_ptr_ = mojo_manager_->CreateCameraAlgorithmOpsPtr(
          cros::constants::kCrosCameraAlgoSocketPathString, "test");
      break;
  }
  if (!interface_ptr_) {
    LOGF(ERROR) << "Failed to connect to the server";
    cb.Run(-EAGAIN);
    return;
  }
  interface_ptr_.set_connection_error_handler(base::Bind(
      &CameraAlgorithmBridgeImpl::IPCBridge::OnConnectionError, GetWeakPtr()));
  cb_impl_.reset(
      new CameraAlgorithmCallbackOpsImpl(ipc_task_runner_, callback_ops));
  interface_ptr_->Initialize(cb_impl_->CreateInterfacePtr(), cb);
  callback_ops_ = callback_ops;
  VLOGF_EXIT();
}

void CameraAlgorithmBridgeImpl::IPCBridge::RegisterBuffer(
    int buffer_fd, base::Callback<void(int32_t)> cb) {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  VLOGF_ENTER();
  if (!interface_ptr_.is_bound()) {
    LOGF(ERROR) << "Interface is not bound probably because IPC is broken";
    cb.Run(-ECONNRESET);
    return;
  }
  int dup_fd = dup(buffer_fd);
  if (dup_fd < 0) {
    PLOGF(ERROR) << "Failed to dup fd: ";
    cb.Run(-errno);
    return;
  }
  interface_ptr_->RegisterBuffer(
      mojo::WrapPlatformFile(base::ScopedPlatformFile(dup_fd)), cb);
}

void CameraAlgorithmBridgeImpl::IPCBridge::Request(
    uint32_t req_id, std::vector<uint8_t> req_header, int32_t buffer_handle) {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  VLOGF_ENTER();
  if (!interface_ptr_.is_bound()) {
    LOGF(ERROR) << "Interface is not bound probably because IPC is broken";
    return;
  }
  interface_ptr_->Request(req_id, std::move(req_header), buffer_handle);
  VLOGF_EXIT();
}

void CameraAlgorithmBridgeImpl::IPCBridge::DeregisterBuffers(
    std::vector<int32_t> buffer_handles) {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  VLOGF_ENTER();
  if (!interface_ptr_.is_bound()) {
    LOGF(ERROR) << "Interface is not bound probably because IPC is broken";
    return;
  }
  interface_ptr_->DeregisterBuffers(std::move(buffer_handles));
}

void CameraAlgorithmBridgeImpl::IPCBridge::OnConnectionError() {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  DCHECK(callback_ops_);
  VLOGF_ENTER();
  Destroy();
  if (callback_ops_->notify) {
    callback_ops_->notify(callback_ops_, CAMERA_ALGORITHM_MSG_IPC_ERROR);
  }
  VLOGF_EXIT();
}

void CameraAlgorithmBridgeImpl::IPCBridge::Destroy() {
  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
  VLOGF_ENTER();
  if (interface_ptr_.is_bound()) {
    cb_impl_.reset();
    interface_ptr_.reset();
  }
  VLOGF_EXIT();
}

base::WeakPtr<CameraAlgorithmBridgeImpl::IPCBridge>
CameraAlgorithmBridgeImpl::IPCBridge::GetWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

}  // namespace cros
