/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_H
#define GRPC_CORE_LIB_IOMGR_EXECUTOR_H

#include <grpc/support/port_platform.h>

#include "src/core/lib/gpr/spinlock.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/closure.h"

namespace grpc_core {

struct ThreadState {
  gpr_mu mu;
  size_t id;         // For debugging purposes
  const char* name;  // Thread state name
  gpr_cv cv;
  grpc_closure_list elems;
  size_t depth;  // Number of closures in the closure list
  bool shutdown;
  bool queued_long_job;
  grpc_core::Thread thd;
};

enum class ExecutorType {
  DEFAULT = 0,
  RESOLVER,

  NUM_EXECUTORS  // Add new values above this
};

enum class ExecutorJobType {
  SHORT = 0,
  LONG,
  NUM_JOB_TYPES  // Add new values above this
};

class Executor {
 public:
  Executor(const char* executor_name);

  void Init();

  /** Is the executor multi-threaded? */
  bool IsThreaded() const;

  /* Enable/disable threading - must be called after Init and Shutdown(). Never
   * call SetThreading(false) in the middle of an application */
  void SetThreading(bool threading);

  /** Shutdown the executor, running all pending work as part of the call */
  void Shutdown();

  /** Enqueue the closure onto the executor. is_short is true if the closure is
   * a short job (i.e expected to not block and complete quickly) */
  void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short);

  // TODO(sreek): Currently we have two executors (available globally): The
  // default executor and the resolver executor.
  //
  // Some of the functions below operate on the DEFAULT executor only while some
  // operate of ALL the executors. This is a bit confusing and should be cleaned
  // up in future (where we make all the following functions take ExecutorType
  // and/or JobType)

  // Initialize ALL the executors
  static void InitAll();

  static void Run(grpc_closure* closure, grpc_error* error,
                  ExecutorType executor_type = ExecutorType::DEFAULT,
                  ExecutorJobType job_type = ExecutorJobType::SHORT);

  // Shutdown ALL the executors
  static void ShutdownAll();

  // Set the threading mode for ALL the executors
  static void SetThreadingAll(bool enable);

  // Set the threading mode for ALL the executors
  static void SetThreadingDefault(bool enable);

  // Return if a given executor is running in threaded mode (i.e if
  // SetThreading(true) was called previously on that executor)
  static bool IsThreaded(ExecutorType executor_type);

  // Return if the DEFAULT executor is threaded
  static bool IsThreadedDefault();

 private:
  static size_t RunClosures(const char* executor_name, grpc_closure_list list);
  static void ThreadMain(void* arg);

  const char* name_;
  ThreadState* thd_state_;
  size_t max_threads_;
  gpr_atm num_threads_;
  gpr_spinlock adding_thread_lock_;
};

// Global initializer for executor
void grpc_executor_global_init();

}  // namespace grpc_core

#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */
