/*
 * Copyright 2016 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 "cros-camera/future.h"

#include <base/time/time.h>

namespace cros {

namespace internal {

FutureLock::FutureLock(CancellationRelay* relay)
    : cond_(&lock_), cancelled_(false), signalled_(false), relay_(relay) {
  VLOGF_ENTER();
  if (relay_ && !relay_->AddObserver(this)) {
    cancelled_ = true;
  }
}

FutureLock::~FutureLock() {
  VLOGF_ENTER();
  base::AutoLock l(lock_);
  if (relay_) {
    relay_->RemoveObserver(this);
  }
}

void FutureLock::Signal() {
  VLOGF_ENTER();
  base::AutoLock l(lock_);
  signalled_ = true;
  cond_.Signal();
}

bool FutureLock::Wait(int timeout_ms) {
  VLOGF_ENTER();
  base::AutoLock l(lock_);

  base::TimeTicks end_time =
      base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(timeout_ms);
  while (!signalled_ && !cancelled_) {
    if (timeout_ms > 0) {
      // Wait until the FutureLock is signalled or timeout.
      base::TimeTicks now = base::TimeTicks::Now();
      if (end_time > now) {
        cond_.TimedWait(end_time - now);
      } else {
        LOGF(ERROR) << "FutureLock wait timeout";
        return false;
      }
    } else {
      // Wait indefinitely until the FutureLock is signalled.
      cond_.Wait();
    }
  }

  if (cancelled_) {
    LOGF(ERROR) << "FutureLock was cancelled";
  }
  return !cancelled_;
}

void FutureLock::Cancel() {
  VLOGF_ENTER();
  base::AutoLock l(lock_);
  cancelled_ = true;
  relay_ = nullptr;
  cond_.Signal();
}

}  // namespace internal

base::Callback<void()> GetFutureCallback(
    const scoped_refptr<Future<void>>& future) {
  return base::Bind(&Future<void>::Set, future);
}

CancellationRelay::CancellationRelay() : cancelled_(false) {}

CancellationRelay::~CancellationRelay() {
  CancelAllFutures();
}

bool CancellationRelay::AddObserver(internal::FutureLock* future_lock) {
  VLOGF_ENTER();
  base::AutoLock l(lock_);
  if (cancelled_) {
    return false;
  }
  observers_.insert(future_lock);
  return true;
}

void CancellationRelay::RemoveObserver(internal::FutureLock* future_lock) {
  VLOGF_ENTER();
  base::AutoLock l(lock_);
  auto it = observers_.find(future_lock);
  if (it != observers_.end()) {
    observers_.erase(it);
  }
}

void CancellationRelay::CancelAllFutures() {
  VLOGF_ENTER();
  base::AutoLock l(lock_);
  cancelled_ = true;
  for (auto it : observers_) {
    it->Cancel();
  }
  observers_.clear();
}

}  // namespace cros
