//===-- MICmdInvoker.cpp ----------------------------------------*- 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
//
//===----------------------------------------------------------------------===//

// In-house headers:
#include "MICmdInvoker.h"
#include "MICmdBase.h"
#include "MICmdMgr.h"
#include "MICmnLog.h"
#include "MICmnStreamStdout.h"
#include "MIDriver.h"

//++
//------------------------------------------------------------------------------------
// Details: CMICmdInvoker constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdInvoker::CMICmdInvoker() : m_rStreamOut(CMICmnStreamStdout::Instance()) {}

//++
//------------------------------------------------------------------------------------
// Details: CMICmdInvoker destructor.
// Type:    Overridable.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmdInvoker::~CMICmdInvoker() { Shutdown(); }

//++
//------------------------------------------------------------------------------------
// Details: Initialize resources for *this Command Invoker.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdInvoker::Initialize() {
  m_clientUsageRefCnt++;

  if (m_bInitialized)
    return MIstatus::success;

  m_bInitialized = true;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdInvoker::Shutdown() {
  if (--m_clientUsageRefCnt > 0)
    return MIstatus::success;

  if (!m_bInitialized)
    return MIstatus::success;

  CmdDeleteAll();

  m_bInitialized = false;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Empty the map of invoked commands doing work. Command objects are
// deleted too.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void CMICmdInvoker::CmdDeleteAll() {
  CMICmdMgr &rMgr = CMICmdMgr::Instance();
  MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.begin();
  while (it != m_mapCmdIdToCmd.end()) {
    const MIuint cmdId((*it).first);
    MIunused(cmdId);
    CMICmdBase *pCmd = (*it).second;
    const CMIUtilString &rCmdName(pCmd->GetCmdData().strMiCmd);
    MIunused(rCmdName);
    rMgr.CmdDelete(pCmd->GetCmdData());

    // Next
    ++it;
  }
  m_mapCmdIdToCmd.clear();
}

//++
//------------------------------------------------------------------------------------
// Details: Remove from the map of invoked commands doing work a command that
// has finished
//          its work. The command object is deleted too.
// Type:    Method.
// Args:    vId             - (R) Command object's unique ID.
//          vbYesDeleteCmd  - (R) True = Delete command object, false = delete
//          via the Command Manager.
// Return:  None.
// Throws:  None.
//--
bool CMICmdInvoker::CmdDelete(const MIuint vId,
                              const bool vbYesDeleteCmd /*= false*/) {
  CMICmdMgr &rMgr = CMICmdMgr::Instance();
  MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.find(vId);
  if (it != m_mapCmdIdToCmd.end()) {
    CMICmdBase *pCmd = (*it).second;
    if (vbYesDeleteCmd) {
      // Via registered interest command manager callback *this object to delete
      // the command
      m_mapCmdIdToCmd.erase(it);
      delete pCmd;
    } else
      // Notify other interested object of this command's pending deletion
      rMgr.CmdDelete(pCmd->GetCmdData());
  }

  if (m_mapCmdIdToCmd.empty())
    rMgr.CmdUnregisterForDeleteNotification(*this);

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Add to the map of invoked commands doing work a command that is
// about to
//          start to do work.
// Type:    Method.
// Args:    vCmd    - (R) Command object.
// Return:  None.
// Throws:  None.
//--
bool CMICmdInvoker::CmdAdd(const CMICmdBase &vCmd) {
  if (m_mapCmdIdToCmd.empty()) {
    CMICmdMgr &rMgr = CMICmdMgr::Instance();
    rMgr.CmdRegisterForDeleteNotification(*this);
  }

  const MIuint &cmdId(vCmd.GetCmdData().id);
  MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.find(cmdId);
  if (it != m_mapCmdIdToCmd.end())
    return MIstatus::success;

  MapPairCmdIdToCmd_t pr(cmdId, const_cast<CMICmdBase *>(&vCmd));
  m_mapCmdIdToCmd.insert(pr);

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Having previously had the potential command validated and found
// valid now
//          get the command executed.
//          If the Functionality returns MIstatus::failure call
//          GetErrorDescription().
//          This function is used by the application's main thread.
// Type:    Method.
// Args:    vCmd    - (RW) Command object.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmdInvoker::CmdExecute(CMICmdBase &vCmd) {
  bool bOk = CmdAdd(vCmd);

  if (bOk) {
    vCmd.AddCommonArgs();
    if (!vCmd.ParseArgs()) {
      // Report command execution failed
      const SMICmdData cmdData(vCmd.GetCmdData());
      CmdStdout(cmdData);
      CmdCauseAppExit(vCmd);
      CmdDelete(cmdData.id);

      // Proceed to wait or execute next command
      return MIstatus::success;
    }
  }

  if (bOk && !vCmd.Execute()) {
    // Report command execution failed
    const SMICmdData cmdData(vCmd.GetCmdData());
    CmdStdout(cmdData);
    CmdCauseAppExit(vCmd);
    CmdDelete(cmdData.id);

    // Proceed to wait or execute next command
    return MIstatus::success;
  }

  bOk = CmdExecuteFinished(vCmd);

  return bOk;
}

//++
//------------------------------------------------------------------------------------
// Details: Called when a command has finished its Execution() work either
// synchronously
//          because the command executed was the type a non event type or
//          asynchronously
//          via the command's callback (because of an SB Listener event). Needs
//          to be called
//          so that *this invoker call do some house keeping and then proceed to
//          call
//          the command's Acknowledge() function.
// Type:    Method.
// Args:    vCmd    - (R) Command object.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmdInvoker::CmdExecuteFinished(CMICmdBase &vCmd) {
  // Command finished now get the command to gather it's information and form
  // the MI
  // Result record
  if (!vCmd.Acknowledge()) {
    // Report command acknowledge functionality failed
    const SMICmdData cmdData(vCmd.GetCmdData());
    CmdStdout(cmdData);
    CmdCauseAppExit(vCmd);
    CmdDelete(cmdData.id);

    // Proceed to wait or execute next command
    return MIstatus::success;
  }

  // Retrieve the command's latest data/information. Needed for commands of the
  // event type so have
  // a record of commands pending finishing execution.
  const CMIUtilString &rMIResultRecord(vCmd.GetMIResultRecord());
  SMICmdData cmdData(
      vCmd.GetCmdData()); // Make a copy as the command will be deleted soon
  cmdData.strMiCmdResultRecord = rMIResultRecord; // Precautionary copy as the
                                                  // command might forget to do
                                                  // this
  if (vCmd.HasMIResultRecordExtra()) {
    cmdData.bHasResultRecordExtra = true;
    const CMIUtilString &rMIExtra(vCmd.GetMIResultRecordExtra());
    cmdData.strMiCmdResultRecordExtra =
        rMIExtra; // Precautionary copy as the command might forget to do this
  }

  // Send command's MI response to the client
  bool bOk = CmdStdout(cmdData);

  // Delete the command object as do not require anymore
  bOk = bOk && CmdDelete(vCmd.GetCmdData().id);

  return bOk;
}

//++
//------------------------------------------------------------------------------------
// Details: If the MI Driver is not operating via a client i.e. Eclipse check
// the command
//          on failure suggests the application exits. A command can be such
//          that a
//          failure cannot the allow the application to continue operating.
// Args:    vCmd    - (R) Command object.
// Return:  None.
// Return:  None.
// Throws:  None.
//--
void CMICmdInvoker::CmdCauseAppExit(const CMICmdBase &vCmd) const {
  if (vCmd.GetExitAppOnCommandFailure()) {
    CMIDriver &rDriver(CMIDriver::Instance());
    if (rDriver.IsDriverDebuggingArgExecutable()) {
      rDriver.SetExitApplicationFlag(true);
    }
  }
}

//++
//------------------------------------------------------------------------------------
// Details: Write to stdout and the Log file the command's MI formatted result.
// Type:    vCmdData    - (R) A command's information.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Return:  None.
// Throws:  None.
//--
bool CMICmdInvoker::CmdStdout(const SMICmdData &vCmdData) const {
  bool bOk = m_pLog->WriteLog(vCmdData.strMiCmdAll);
  const bool bLock = bOk && m_rStreamOut.Lock();
  bOk = bOk && bLock &&
        m_rStreamOut.WriteMIResponse(vCmdData.strMiCmdResultRecord);
  if (bOk && vCmdData.bHasResultRecordExtra) {
    bOk = m_rStreamOut.WriteMIResponse(vCmdData.strMiCmdResultRecordExtra);
  }
  bOk = bLock && m_rStreamOut.Unlock();

  return bOk;
}

//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdMgr::ICmdDeleteCallback. *this object is
// registered
//          with the Command Manager to receive callbacks when a command is
//          being deleted.
//          An object, *this invoker, does not delete a command object itself
//          but calls
//          the Command Manager to delete a command object. This function is the
//          Invoker's
//          called.
//          The Invoker owns the command objects and so can delete them but must
//          do it
//          via the manager so other objects can be notified of the deletion.
// Type:    Method.
// Args:    vCmd    - (RW) Command.
// Return:  None.
// Throws:  None.
//--
void CMICmdInvoker::Delete(SMICmdData &vCmd) { CmdDelete(vCmd.id, true); }
