//===-- MICmnLog.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 "MICmnLog.h"
#include "MICmnLogMediumFile.h"
#include "MICmnResources.h"
#include "MIDriverMgr.h"
#include "MIUtilDateTimeStd.h"

//++
//------------------------------------------------------------------------------------
// Details: CMICmnLog constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmnLog::CMICmnLog() : m_bEnabled(false), m_bInitializingATM(false) {
  // Do not use this constructor, use Initialize()
}

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

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

  if (m_bInitialized)
    return MIstatus::success;

  ClrErrorDescription();

  // Mediums set inside because explicitly initing in MIDriverMain.cpp causes
  // compile errors with CAtlFile
  CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance());
  bool bOk = RegisterMedium(rFileLog);
  if (bOk) {
    // Set the Log trace file's header
    const CMIUtilString &rCR(rFileLog.GetLineReturn());
    CMIUtilDateTimeStd date;
    CMIUtilString msg;
    msg = CMIUtilString::Format(
        "%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str());
    CMIUtilString logHdr(msg);
    msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_CREATION_DATE),
                                date.GetDate().c_str(), date.GetTime().c_str(),
                                rCR.c_str());
    logHdr += msg;
    msg =
        CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_FILE_LOGGER_PATH),
                              rFileLog.GetFileNamePath().c_str(), rCR.c_str());
    logHdr += msg;

    bOk = rFileLog.SetHeaderTxt(logHdr);

    // Note log file medium's status is not available until we write at least
    // once to the file (so just write the title 1st line)
    m_bInitializingATM = true;
    CMICmnLog::WriteLog(".");
    if (!rFileLog.IsOk()) {
      const CMIUtilString msg(
          CMIUtilString::Format(MIRSRC(IDS_LOG_ERR_FILE_LOGGER_DISABLED),
                                rFileLog.GetErrorDescription().c_str()));
      CMICmnLog::WriteLog(msg);
    }
    m_bInitializingATM = false;
  }

  m_bInitialized = bOk;

  return bOk;
}

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

  if (!m_bInitialized)
    return MIstatus::success;

  ClrErrorDescription();

  const bool bOk = UnregisterMediumAll();

  m_bInitialized = bOk;

  return bOk;
}

//++
//------------------------------------------------------------------------------------
// Details: Enabled or disable *this Logger from writing any data to registered
// clients.
// Type:    Method.
// Args:    vbYes   - (R) True = Logger enabled, false = disabled.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnLog::SetEnabled(const bool vbYes) {
  m_bEnabled = vbYes;

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Retrieve state whether *this Logger is enabled writing data to
// registered clients.
// Type:    Method.
// Args:    None.
// Return:  True = Logger enable.
//          False = disabled.
// Throws:  None.
//--
bool CMICmnLog::GetEnabled() const { return m_bEnabled; }

//++
//------------------------------------------------------------------------------------
// Details: Unregister all the Mediums registered with *this Logger.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnLog::UnregisterMediumAll() {
  MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
  for (; it != m_mapMediumToName.end(); it++) {
    IMedium *pMedium = (*it).first;
    pMedium->Shutdown();
  }

  m_mapMediumToName.clear();

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Register a Medium with *this Logger.
// Type:    Method.
// Args:    vrMedium    - (R) The medium to register.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnLog::RegisterMedium(const IMedium &vrMedium) {
  if (HaveMediumAlready(vrMedium))
    return MIstatus::success;

  IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
  if (!pMedium->Initialize()) {
    const CMIUtilString &rStrMedName(pMedium->GetName());
    const CMIUtilString &rStrMedErr(pMedium->GetError());
    SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LOG_MEDIUM_ERR_INIT),
                                              rStrMedName.c_str(),
                                              rStrMedErr.c_str()));
    return MIstatus::failure;
  }

  MapPairMediumToName_t pr(pMedium, pMedium->GetName());
  m_mapMediumToName.insert(pr);

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: Query the Logger to see if a medium is already registered.
// Type:    Method.
// Args:    vrMedium    - (R) The medium to query.
// Return:  True - registered.
//          False - not registered.
// Throws:  None.
//--
bool CMICmnLog::HaveMediumAlready(const IMedium &vrMedium) const {
  IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
  const MapMediumToName_t::const_iterator it = m_mapMediumToName.find(pMedium);
  return it != m_mapMediumToName.end();
}

//++
//------------------------------------------------------------------------------------
// Details: Unregister a medium from the Logger.
// Type:    Method.
// Args:    vrMedium    - (R) The medium to unregister.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnLog::UnregisterMedium(const IMedium &vrMedium) {
  IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
  m_mapMediumToName.erase(pMedium);

  return MIstatus::success;
}

//++
//------------------------------------------------------------------------------------
// Details: The callee client uses this function to write to the Logger. The
// data to be
//          written is given out to all the mediums registered. The verbosity
//          type parameter
//          indicates to the medium(s) the type of data or message given to it.
//          The medium has
//          modes of verbosity and depending on the verbosity set determines
//          which writes
//          go in to the logger.
//          The logger must be initialized successfully before a write to any
//          registered
//          can be carried out.
// Type:    Method.
// Args:    vData       - (R) The data to write to the logger.
//          veType      - (R) Verbosity type.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnLog::Write(const CMIUtilString &vData, const ELogVerbosity veType) {
  if (!m_bInitialized && !m_bInitializingATM)
    return MIstatus::success;
  if (m_bRecursiveDive)
    return MIstatus::success;
  if (!m_bEnabled)
    return MIstatus::success;

  m_bRecursiveDive = true;

  MIuint cnt = 0;
  MIuint cntErr = 0;
  {
    MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
    while (it != m_mapMediumToName.end()) {
      IMedium *pMedium = (*it).first;
      const CMIUtilString &rNameMedium = (*it).second;
      MIunused(rNameMedium);
      if (pMedium->Write(vData, veType))
        cnt++;
      else
        cntErr++;

      // Next
      ++it;
    }
  }

  bool bOk = MIstatus::success;
  const MIuint mediumCnt = m_mapMediumToName.size();
  if ((cnt == 0) && (mediumCnt > 0)) {
    SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_ANY));
    bOk = MIstatus::failure;
  }
  if (bOk && (cntErr != 0)) {
    SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL));
    bOk = MIstatus::failure;
  }

  m_bRecursiveDive = false;

  return bOk;
}

//++
//------------------------------------------------------------------------------------
// Details: Short cut function call to write only to the Log file.
//          The logger must be initialized successfully before a write to any
//          registered
//          can be carried out.
// Type:    Static.
// Args:    vData   - (R) The data to write to the logger.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmnLog::WriteLog(const CMIUtilString &vData) {
  return CMICmnLog::Instance().Write(vData, CMICmnLog::eLogVerbosity_Log);
}

//++
//------------------------------------------------------------------------------------
// Details: Retrieve a string detailing the last error.
// Type:    Method.
// Args:    None,
// Return:  CMIUtilString.
// Throws:  None.
//--
const CMIUtilString &CMICmnLog::GetErrorDescription() const {
  return m_strMILastErrorDescription;
}

//++
//------------------------------------------------------------------------------------
// Details: Set the internal description of the last error.
// Type:    Method.
// Args:    (R) String containing a description of the last error.
// Return:  None.
// Throws:  None.
//--
void CMICmnLog::SetErrorDescription(const CMIUtilString &vrTxt) const {
  m_strMILastErrorDescription = vrTxt;
}

//++
//------------------------------------------------------------------------------------
// Details: Clear the last error.
// Type:    None.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void CMICmnLog::ClrErrorDescription() const {
  m_strMILastErrorDescription = CMIUtilString("");
}
