/*
 * Copyright 2018 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "starboard/common/thread.h"

#include "starboard/atomic.h"
#include "starboard/common/optional.h"
#include "starboard/common/semaphore.h"
#include "starboard/log.h"
#include "starboard/mutex.h"
#include "starboard/thread.h"
#include "starboard/time.h"
#include "starboard/types.h"

namespace starboard {

struct Thread::Data {
  std::string name_;
  SbThread thread_ = kSbThreadInvalid;
  atomic_bool started_;
  atomic_bool join_called_;
  Semaphore join_sema_;
  optional<Thread::Options> options_;
};

Thread::Thread(const std::string& name) {
  d_.reset(new Thread::Data);
  d_->name_ = name;
}

Thread::~Thread() {
  SB_DCHECK(d_->join_called_.load()) << "Join not called on thread.";
}

void Thread::Start(const Options& options) {
  SbThreadEntryPoint entry_point = ThreadEntryPoint;

  SB_DCHECK(!d_->started_.load());
  SB_DCHECK(!d_->options_.has_engaged());
  d_->started_.store(true);
  d_->options_ = options;

  d_->thread_ = SbThreadCreate(options.stack_size,
                               options.priority_,
                               kSbThreadNoAffinity,  // default affinity.
                               options.joinable,
                               d_->name_.c_str(),
                               entry_point,
                               this);

  // SbThreadCreate() above produced an invalid thread handle.
  SB_DCHECK(d_->thread_ != kSbThreadInvalid);
}

void Thread::Sleep(SbTime microseconds) {
  SbThreadSleep(microseconds);
}

void Thread::SleepMilliseconds(int value) {
  return Sleep(value * kSbTimeMillisecond);
}

bool Thread::WaitForJoin(SbTime timeout) {
  bool joined = d_->join_sema_.TakeWait(timeout);
  if (joined) {
    SB_DCHECK(d_->join_called_.load());
  }
  return joined;
}

starboard::Semaphore* Thread::join_sema() {
  return &d_->join_sema_;
}

starboard::atomic_bool* Thread::joined_bool() {
  return &d_->join_called_;
}

void* Thread::ThreadEntryPoint(void* context) {
  Thread* this_ptr = static_cast<Thread*>(context);
  this_ptr->Run();
  return NULL;
}

void Thread::Join() {
  SB_DCHECK(d_->join_called_.load() == false);
  SB_DCHECK(d_->options_->joinable)
      << "Detached thread should not be joined.";

  d_->join_called_.store(true);
  d_->join_sema_.Put();

  if (!SbThreadJoin(d_->thread_, NULL)) {
    SB_DCHECK(false) << "Could not join thread.";
  }
}

bool Thread::join_called() const {
  return d_->join_called_.load();
}

}  // namespace starboard
