/*
 * Copyright 2013 Google Inc.
 *
 * 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.
 */

// Author: jmarantz@google.com (Joshua Marantz)
//
// Zero-dependency mock thread-system for use in tests that don't
// actually use threads, to help test classes that need some mutexing
// or other thread-safety hooks.
//
// Note that this thread-system does not currently make threads (even
// co-routines), but check-fails if you attempt to spawn a new thread.

#ifndef PAGESPEED_KERNEL_BASE_NULL_THREAD_SYSTEM_H_
#define PAGESPEED_KERNEL_BASE_NULL_THREAD_SYSTEM_H_

#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/condvar.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"

namespace net_instaweb {

class Timer;

class NullCondvar : public ThreadSystem::Condvar {
 public:
  explicit NullCondvar(ThreadSystem::CondvarCapableMutex* m)
      : mutex_(m), timed_wait_callback_(NULL) {}
  virtual ~NullCondvar();
  virtual ThreadSystem::CondvarCapableMutex* mutex() const { return mutex_; }
  virtual void Signal() { actions_.push_back("Signal()"); }
  virtual void Broadcast() { actions_.push_back("Broadcast()"); }
  virtual void Wait() { actions_.push_back("Wait()"); }
  virtual void TimedWait(int64 timeout_ms);
  GoogleString ActionsSinceLastCall();

  class TimedWaitCallback {
   public:
    virtual ~TimedWaitCallback() {}
    virtual void Call() = 0;
  };

  // Calls callback once the next time TimedWait() is called.  If TimedWait() is
  // not called we will CHECK-fail.  Doesn't take ownership of the callback.
  void set_timed_wait_callback(TimedWaitCallback* x) {
    CHECK(timed_wait_callback_ == NULL);
    timed_wait_callback_ = x;
  }

 private:
  ThreadSystem::CondvarCapableMutex* mutex_;
  StringVector actions_;
  TimedWaitCallback* timed_wait_callback_;

  DISALLOW_COPY_AND_ASSIGN(NullCondvar);
};

// Mock condvar-capable mutex.  Note that this does no actual locking,
// and any condvars it creates are mocks.
class NullCondvarCapableMutex : public ThreadSystem::CondvarCapableMutex {
 public:
  NullCondvarCapableMutex() {}
  virtual ~NullCondvarCapableMutex();
  virtual bool TryLock() { return true; }
  virtual void Lock() {}
  virtual void Unlock() {}
  virtual NullCondvar* NewCondvar();

 private:
  DISALLOW_COPY_AND_ASSIGN(NullCondvarCapableMutex);
};

// Mock thread system.  This can create mutexes that do no locking, condvars
// that do no waiting, and can't create threads.  Trying to create a thread will
// result in a fatal error.
class NullThreadSystem : public ThreadSystem {
 public:
  NullThreadSystem() : thread_id_(1) {}
  virtual ~NullThreadSystem();
  virtual NullCondvarCapableMutex* NewMutex();
  virtual RWLock* NewRWLock();
  virtual Timer* NewTimer();
  virtual ThreadId* GetThreadId() const;

  // Provide injection/observation of current thread IDs.
  void set_current_thread(int id) { thread_id_ = id; }
  int current_thread() const { return thread_id_; }

 private:
  virtual ThreadImpl* NewThreadImpl(Thread* wrapper, ThreadFlags flags);

 private:
  int thread_id_;

  DISALLOW_COPY_AND_ASSIGN(NullThreadSystem);
};

}  // namespace net_instaweb

#endif  // PAGESPEED_KERNEL_BASE_NULL_THREAD_SYSTEM_H_
