//===-- MICmnStreamStdout.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 "MICmnStreamStdout.h"
#include "MICmnLog.h"
#include "MICmnResources.h"
#include "MIDriver.h"

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

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

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

  if (m_bInitialized)
    return MIstatus::success;

  bool bOk = MIstatus::success;

#ifdef _MSC_VER
// Debugging / I/O issues with client.
// This is only required on Windows if you do not use ::flush(stdout). MI uses
// ::flush(stdout)
// It trys to ensure the process attached to the stdout steam gets ALL the data.
//::setbuf( stdout, NULL );
#endif // _MSC_VER

  m_bInitialized = bOk;

  return MIstatus::success;
}

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

  if (!m_bInitialized)
    return MIstatus::success;

  ClrErrorDescription();

  m_bInitialized = false;

  return MIstatus::success;
}

//++
// Details: Write an MI format type response to stdout. The text data does not
// need to
//          include a carriage line return as this is added to the text. The
//          function also
//          then passes the text data into the CMICmnLog logger.
// Type:    Method.
// Args:    vText       - (R) MI formatted text.
//          vbSendToLog - (R) True = Yes send to the Log file too, false = do
//          not. (Dflt = true)
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::WriteMIResponse(const CMIUtilString &vText,
                                         const bool vbSendToLog /* = true */) {
  return WritePriv(vText, vText, vbSendToLog);
}

//++
// Details: Write text data to stdout. The text data does not need to
//          include a carriage line return as this is added to the text. The
//          function also
//          then passes the text data into the CMICmnLog logger.
// Type:    Method.
// Args:    vText       - (R) Text data.
//          vbSendToLog - (R) True = Yes send to the Log file too, false = do
//          not. (Dflt = true)
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::Write(const CMIUtilString &vText,
                               const bool vbSendToLog /* = true */) {
  if (vText.length() == 0)
    return MIstatus::failure;

  const CMIUtilString strPrefixed(CMIUtilString::Format(
      "%s: %s", CMIDriver::Instance().GetAppNameShort().c_str(),
      vText.c_str()));

  return WritePriv(strPrefixed, vText, vbSendToLog);
}

//++
// Details: Write text data to stdout. The text data does not need to
//          include a carriage line return as this is added to the text. The
//          function also
//          then passes the text data into the CMICmnLog logger.
// Type:    Method.
// Args:    vText           - (R) Text data prefixed with MI app's short name.
//          vTxtForLogFile  - (R) Text data.
//          vbSendToLog     - (R) True = Yes send to the Log file too, false =
//          do not. (Dflt = true)
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::WritePriv(const CMIUtilString &vText,
                                   const CMIUtilString &vTxtForLogFile,
                                   const bool vbSendToLog /* = true */) {
  if (vText.length() == 0)
    return MIstatus::failure;

  bool bOk = MIstatus::success;
  {
    // Grab the stdout thread lock while we print
    CMIUtilThreadLock _lock(m_mutex);

    // Send this text to stdout
    const MIint status = ::fputs(vText.c_str(), stdout);
    if (status == EOF)
      // Don't call the CMICmnBase::SetErrorDescription() because it will cause
      // a stack overflow:
      // CMICmnBase::SetErrorDescription -> CMICmnStreamStdout::Write ->
      // CMICmnStreamStdout::WritePriv -> CMICmnBase::SetErrorDescription
      bOk = MIstatus::failure;
    else {
      ::fprintf(stdout, "\n");
      ::fflush(stdout);
    }

    // Send this text to the log
    if (bOk && vbSendToLog)
      bOk &= m_pLog->WriteLog(vTxtForLogFile);
  }

  return bOk;
}

//++
// Details: Lock the availability of the stream stdout. Other users of *this
// stream will
//          be stalled until it is available (Unlock()).
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::Lock() {
  m_mutex.Lock();
  return MIstatus::success;
}

//++
// Details: Release a previously locked stdout.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::Unlock() {
  m_mutex.Unlock();
  return MIstatus::success;
}

//++
// Details: Take a text data and send to the stdout stream. Also output to the
// MI Log
//          file.
// Type:    Static method.
// Args:    vrTxt   - (R) Text.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::TextToStdout(const CMIUtilString &vrTxt) {
  const bool bSendToLog = true;
  return CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt, bSendToLog);
}

//++
// Details: Write prompt to stdout if it's enabled.
// Type:    Static method.
// Args:    None.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmnStreamStdout::WritePrompt() {
  const CMICmnStreamStdin &rStdinMan = CMICmnStreamStdin::Instance();
  if (rStdinMan.GetEnablePrompt())
    return TextToStdout(rStdinMan.GetPrompt());
  return MIstatus::success;
}
