/*
 * 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.
 */

#ifndef CAMERA_INCLUDE_CROS_CAMERA_CAMERA_THREAD_H_
#define CAMERA_INCLUDE_CROS_CAMERA_CAMERA_THREAD_H_

#include <string>
#include <unordered_map>

#include <base/location.h>
#include <base/threading/thread.h>

#include "cros-camera/common.h"
#include "cros-camera/export.h"
#include "cros-camera/future.h"

namespace cros {

class CROS_CAMERA_EXPORT CameraThread {
 public:
  explicit CameraThread(std::string name) : thread_(name) {}

  // Starts the thread. Returns true if the thread was successfully started.
  bool Start() {
    if (!thread_.Start()) {
      LOG(ERROR) << "Failed to start thread";
      return false;
    }
    thread_.WaitUntilThreadStarted();
    return true;
  }

  // Stop the thread. This function is expected to be called explicitly. A fatal
  // error would have occured in the AtExitManager if it were called in
  // the destructor.
  void Stop() { thread_.Stop(); }

  // Returns true if this is the current thread that is running.
  bool IsCurrentThread() const {
    return thread_.GetThreadId() == base::PlatformThread::CurrentId();
  }

  // Posts the given task to be run and wait till it is finished. The reply
  // from callee will be stored in |result|. Return 0 if succeed. Otherwise
  // return -EIO.
  template <typename T>
  int PostTaskSync(const base::Location& from_here,
                   base::Callback<T()> task,
                   T* result) {
    VLOGF_ENTER();
    if (!thread_.task_runner()) {
      LOG(ERROR) << "Thread is not started";
      return -EIO;
    }

    auto future = cros::Future<T>::Create(nullptr);
    base::Closure closure =
        base::Bind(&CameraThread::ProcessSyncTaskOnThread<T>,
                   base::Unretained(this), task, future);
    if (!thread_.task_runner()->PostTask(from_here, closure)) {
      LOG(ERROR) << "Failed to post task";
      return -EIO;
    }

    *result = future->Get();
    return 0;
  }

  // Posts the given task to be run asynchronously. Return 0 if succeed.
  // Otherwise return -EIO.
  template <typename T>
  int PostTaskAsync(const base::Location& from_here, base::Callback<T()> task) {
    VLOGF_ENTER();
    if (!thread_.task_runner()) {
      LOG(ERROR) << "Thread is not started";
      return -EIO;
    }
    base::Closure closure =
        base::Bind(&CameraThread::ProcessASyncTaskOnThread<T>,
                   base::Unretained(this), task);

    if (!thread_.task_runner()->PostTask(from_here, closure)) {
      LOG(ERROR) << "Failed to post task";
      return -EIO;
    }
    return 0;
  }

  // Posts the given task to be run and wait till it is finished.
  // Return 0 if succeed. Otherwise return -EIO.
  int PostTaskSync(const base::Location& from_here, base::Closure task) {
    VLOGF_ENTER();
    if (!thread_.task_runner()) {
      LOG(ERROR) << "Thread is not started";
      return -EIO;
    }

    auto future = cros::Future<void>::Create(nullptr);
    base::Closure closure =
        base::Bind(&CameraThread::ProcessClosureSyncTaskOnThread,
                   base::Unretained(this), task, future);
    if (!thread_.task_runner()->PostTask(from_here, closure)) {
      LOG(ERROR) << "Failed to post task";
      return -EIO;
    }

    future->Wait();
    return 0;
  }

 private:
  template <typename T>
  void ProcessSyncTaskOnThread(const base::Callback<T()>& task,
                               scoped_refptr<cros::Future<T>> future) {
    VLOGF_ENTER();
    future->Set(task.Run());
  }

  template <typename T>
  void ProcessASyncTaskOnThread(const base::Callback<T()>& task) {
    VLOGF_ENTER();
    task.Run();
  }

  void ProcessClosureSyncTaskOnThread(
      const base::Closure& task, scoped_refptr<cros::Future<void>> future) {
    VLOGF_ENTER();
    task.Run();
    future->Set();
  }

  base::Thread thread_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(CameraThread);
};

}  // namespace cros

#endif  // CAMERA_INCLUDE_CROS_CAMERA_CAMERA_THREAD_H_
