/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/base/task.h"
#include "webrtc/base/common.h"
#include "webrtc/base/taskrunner.h"

namespace rtc {

int32_t Task::unique_id_seed_ = 0;

Task::Task(TaskParent *parent)
    : TaskParent(this, parent),
      state_(STATE_INIT),
      blocked_(false),
      done_(false),
      aborted_(false),
      busy_(false),
      error_(false),
      start_time_(0),
      timeout_time_(0),
      timeout_seconds_(0),
      timeout_suspended_(false)  {
  unique_id_ = unique_id_seed_++;

  // sanity check that we didn't roll-over our id seed
  ASSERT(unique_id_ < unique_id_seed_);
}

Task::~Task() {
  // Is this task being deleted in the correct manner?
  ASSERT(!done_ || GetRunner()->is_ok_to_delete(this));
  ASSERT(state_ == STATE_INIT || done_);
  ASSERT(state_ == STATE_INIT || blocked_);

  // If the task is being deleted without being done, it
  // means that it hasn't been removed from its parent.
  // This happens if a task is deleted outside of TaskRunner.
  if (!done_) {
    Stop();
  }
}

int64_t Task::CurrentTime() {
  return GetRunner()->CurrentTime();
}

int64_t Task::ElapsedTime() {
  return CurrentTime() - start_time_;
}

void Task::Start() {
  if (state_ != STATE_INIT)
    return;
  // Set the start time before starting the task.  Otherwise if the task
  // finishes quickly and deletes the Task object, setting start_time_
  // will crash.
  start_time_ = CurrentTime();
  GetRunner()->StartTask(this);
}

void Task::Step() {
  if (done_) {
#ifdef _DEBUG
    // we do not know how !blocked_ happens when done_ - should be impossible.
    // But it causes problems, so in retail build, we force blocked_, and
    // under debug we assert.
    ASSERT(blocked_);
#else
    blocked_ = true;
#endif
    return;
  }

  // Async Error() was called
  if (error_) {
    done_ = true;
    state_ = STATE_ERROR;
    blocked_ = true;
//   obsolete - an errored task is not considered done now
//   SignalDone();

    Stop();
#ifdef _DEBUG
    // verify that stop removed this from its parent
    ASSERT(!parent()->IsChildTask(this));
#endif
    return;
  }

  busy_ = true;
  int new_state = Process(state_);
  busy_ = false;

  if (aborted_) {
    Abort(true);  // no need to wake because we're awake
    return;
  }

  if (new_state == STATE_BLOCKED) {
    blocked_ = true;
    // Let the timeout continue
  } else {
    state_ = new_state;
    blocked_ = false;
    ResetTimeout();
  }

  if (new_state == STATE_DONE) {
    done_ = true;
  } else if (new_state == STATE_ERROR) {
    done_ = true;
    error_ = true;
  }

  if (done_) {
//  obsolete - call this yourself
//    SignalDone();

    Stop();
#if _DEBUG
    // verify that stop removed this from its parent
    ASSERT(!parent()->IsChildTask(this));
#endif
    blocked_ = true;
  }
}

void Task::Abort(bool nowake) {
  // Why only check for done_ (instead of "aborted_ || done_")?
  //
  // If aborted_ && !done_, it means the logic for aborting still
  // needs to be executed (because busy_ must have been true when
  // Abort() was previously called).
  if (done_)
    return;
  aborted_ = true;
  if (!busy_) {
    done_ = true;
    blocked_ = true;
    error_ = true;

    // "done_" is set before calling "Stop()" to ensure that this code 
    // doesn't execute more than once (recursively) for the same task.
    Stop();
#ifdef _DEBUG
    // verify that stop removed this from its parent
    ASSERT(!parent()->IsChildTask(this));
#endif
    if (!nowake) {
      // WakeTasks to self-delete.
      // Don't call Wake() because it is a no-op after "done_" is set.
      // Even if Wake() did run, it clears "blocked_" which isn't desireable.
      GetRunner()->WakeTasks();
    }
  }
}

void Task::Wake() {
  if (done_)
    return;
  if (blocked_) {
    blocked_ = false;
    GetRunner()->WakeTasks();
  }
}

void Task::Error() {
  if (error_ || done_)
    return;
  error_ = true;
  Wake();
}

std::string Task::GetStateName(int state) const {
  switch (state) {
    case STATE_BLOCKED: return "BLOCKED";
    case STATE_INIT: return "INIT";
    case STATE_START: return "START";
    case STATE_DONE: return "DONE";
    case STATE_ERROR: return "ERROR";
    case STATE_RESPONSE: return "RESPONSE";
  }
  return "??";
}

int Task::Process(int state) {
  int newstate = STATE_ERROR;

  if (TimedOut()) {
    ClearTimeout();
    newstate = OnTimeout();
    SignalTimeout();
  } else {
    switch (state) {
      case STATE_INIT:
        newstate = STATE_START;
        break;
      case STATE_START:
        newstate = ProcessStart();
        break;
      case STATE_RESPONSE:
        newstate = ProcessResponse();
        break;
      case STATE_DONE:
      case STATE_ERROR:
        newstate = STATE_BLOCKED;
        break;
    }
  }

  return newstate;
}

void Task::Stop() {
  // No need to wake because we're either awake or in abort
  TaskParent::OnStopped(this);
}

int Task::ProcessResponse() {
  return STATE_DONE;
}

void Task::set_timeout_seconds(const int timeout_seconds) {
  timeout_seconds_ = timeout_seconds;
  ResetTimeout();
}

bool Task::TimedOut() {
  return timeout_seconds_ &&
    timeout_time_ &&
    CurrentTime() >= timeout_time_;
}

void Task::ResetTimeout() {
  int64_t previous_timeout_time = timeout_time_;
  bool timeout_allowed = (state_ != STATE_INIT)
                      && (state_ != STATE_DONE)
                      && (state_ != STATE_ERROR);
  if (timeout_seconds_ && timeout_allowed && !timeout_suspended_)
    timeout_time_ = CurrentTime() +
                    (timeout_seconds_ * kSecToMsec * kMsecTo100ns);
  else
    timeout_time_ = 0;

  GetRunner()->UpdateTaskTimeout(this, previous_timeout_time);
}

void Task::ClearTimeout() {
  int64_t previous_timeout_time = timeout_time_;
  timeout_time_ = 0;
  GetRunner()->UpdateTaskTimeout(this, previous_timeout_time);
}

void Task::SuspendTimeout() {
  if (!timeout_suspended_) {
    timeout_suspended_ = true;
    ResetTimeout();
  }
}

void Task::ResumeTimeout() {
  if (timeout_suspended_) {
    timeout_suspended_ = false;
    ResetTimeout();
  }
}

int Task::OnTimeout() {
  // by default, we are finished after timing out
  return STATE_DONE;
}

} // namespace rtc
