//===-- MICmnThreadMgrStd.h -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

// Third party headers:
#include <vector>

// In-house headers:
#include "MICmnBase.h"
#include "MICmnResources.h"
#include "MIUtilSingletonBase.h"
#include "MIUtilThreadBaseStd.h"

//++
//============================================================================
// Details: MI's worker thread (active thread) manager.
//          The manager creates threads and behalf of clients. Client are
//          responsible for their threads and can delete them when necessary.
//          This manager will stop and delete all threads on *this manager's
//          shutdown.
//          Singleton class.
//--
class CMICmnThreadMgrStd : public CMICmnBase,
                           public MI::ISingleton<CMICmnThreadMgrStd> {
  friend MI::ISingleton<CMICmnThreadMgrStd>;

  // Methods:
public:
  bool Initialize() override;
  bool Shutdown() override;
  bool ThreadAllTerminate(); // Ask all threads to stop (caution)
  template <typename T> // Ask the thread manager to start and stop threads on
                        // our behalf
                        bool ThreadStart(T &vrwObject);

  // Typedef:
private:
  typedef std::vector<CMIUtilThreadActiveObjBase *> ThreadList_t;

  // Methods:
private:
  /* ctor */ CMICmnThreadMgrStd();
  /* ctor */ CMICmnThreadMgrStd(const CMICmnThreadMgrStd &);
  void operator=(const CMICmnThreadMgrStd &);
  //
  bool AddThread(const CMIUtilThreadActiveObjBase &
                     vrObj); // Add a thread for monitoring by the threadmanager

  // Overridden:
private:
  // From CMICmnBase
  /* dtor */ ~CMICmnThreadMgrStd() override;

  // Attributes:
private:
  CMIUtilThreadMutex m_mutex;
  ThreadList_t m_threadList;
};

//++
// Details: Given a thread object start its (worker) thread to do work. The
// object is
//          added to the *this manager for housekeeping and deletion of all
//          thread objects.
// Type:    Template method.
// Args:    vrwThreadObj      - (RW) A CMIUtilThreadActiveObjBase derived
// object.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
template <typename T> bool CMICmnThreadMgrStd::ThreadStart(T &vrwThreadObj) {
  bool bOk = MIstatus::success;

  // Grab a reference to the base object type
  CMIUtilThreadActiveObjBase &rObj =
      static_cast<CMIUtilThreadActiveObjBase &>(vrwThreadObj);

  // Add to the thread managers internal database
  bOk &= AddThread(rObj);
  if (!bOk) {
    const CMIUtilString errMsg(
        CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                              vrwThreadObj.ThreadGetName().c_str()));
    SetErrorDescription(errMsg);
    return MIstatus::failure;
  }

  // Grab a reference on behalf of the caller
  bOk &= vrwThreadObj.Acquire();
  if (!bOk) {
    const CMIUtilString errMsg(
        CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                              vrwThreadObj.ThreadGetName().c_str()));
    SetErrorDescription(errMsg);
    return MIstatus::failure;
  }

  // Thread is already started
  // This call must come after the reference count increment
  if (vrwThreadObj.ThreadIsActive()) {
    // Early exit on thread already running condition
    return MIstatus::success;
  }

  // Start the thread running
  bOk &= vrwThreadObj.ThreadExecute();
  if (!bOk) {
    const CMIUtilString errMsg(
        CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
                              vrwThreadObj.ThreadGetName().c_str()));
    SetErrorDescription(errMsg);
    return MIstatus::failure;
  }

  return MIstatus::success;
}
