//-----------------------------------------------------------
// Copyright Christian Arnault LAL-Orsay CNRS
// arnault@lal.in2p3.fr
// Modified by garonne@lal.in2p3.fr
// Modified by Grigory Rybkin
// See the complete license in cmt_license.txt "http://www.cecill.info". 
//-----------------------------------------------------------

#include "cmt_error.h"
#include "cmt_vector.h"
#include "cmt_log.h"

class TheError
{
public:
  static TheError& instance ();

  TheError ()
  {
    error_names.add() = "ok";
    error_names.add() = "warning";
    error_names.add() = "symbol not found";
    error_names.add() = "pattern not found";
    error_names.add() = "constituent not found";
    error_names.add() = "fragment not found";
    error_names.add() = "language not found";
    error_names.add() = "syntax error";
    error_names.add() = "command not implemented";
    error_names.add() = "package not found";
    error_names.add() = "path not found";
    error_names.add() = "version conflict";
    error_names.add() = "file access error";
    error_names.add() = "system error";
    error_names.add() = "configuration error";
    error_names.add() = "execution error";
    error_names.add() = "cannot lock";
    error_names.add() = "cannot_write_lock";
    error_names.add() = "cannot_run_lock_command";
    error_names.add() = "cannot_unlock";
    error_names.add() = "cannot_run_unlock_command";
    error_names.add() = "cannot_remove_lock";
    error_names.add() = "conflicting_lock";
    error_names.add() = "unknown command";
    error_names.add() = "wrong symbol type";
    error_names.add() = "project release conflict";
    error_names.add() = "execution failed";
    m_execution_error = 0;
  }

  ~TheError ()
  {
  }

  void clear ()
  {
    m_code = CmtError::ok;
    m_text = "";
    m_execution_error = 0 ;
  }

  void set (CmtError::code code, const cmt_string& text, const int execution_error)
  {
    m_code = code;
    m_text = text;
    m_execution_error = execution_error;
  }

  CmtError::code get_code () const
  {
    return (m_code);
  }

  int get_last_execution_error ()
  {
      return m_execution_error;
  }

  const cmt_string& get_text () const
  {
    return (m_text);
  }

  const cmt_string& get_name (CmtError::code error) const
  {
    const cmt_string& s = error_names[error];

    return (s);
  }

private:
  CmtError::code m_code;
  cmt_string m_text;
  cmt_vector<cmt_string> error_names;
  int m_execution_error;
};

//---------------------------------------------------------------
TheError& TheError::instance ()
{
  static TheError e;
  
  return (e);
}

//---------------------------------------------------------------
void CmtError::clear ()
{
  TheError& e = TheError::instance ();

  e.clear ();
}

//---------------------------------------------------------------
bool CmtError::has_pending_error ()
{
  TheError& e = TheError::instance ();

  if (e.get_code () == ok) return (false);
  else return (true);
}

//---------------------------------------------------------------
CmtError::code CmtError::get_last_error_code ()
{
  TheError& e = TheError::instance ();

  return (e.get_code ());
}

//---------------------------------------------------------------
int CmtError::get_last_execution_error ()
{
  TheError& e = TheError::instance ();

  return (e.get_last_execution_error ());
}

//---------------------------------------------------------------
const cmt_string& CmtError::get_error_name (code error)
{
  TheError& e = TheError::instance ();

  return (e.get_name (error));
}

//---------------------------------------------------------------
void CmtError::set (code error, const cmt_string& text, const int execution_error)
{
  TheError& e = TheError::instance ();

  e.set (error, text, execution_error);
}

//---------------------------------------------------------------
cmt_string CmtError::get_last_error ()
{
  TheError& e = TheError::instance ();

  cmt_string result;

  result = get_error_name (e.get_code ());
  result += ": ";
  result += e.get_text ();

  return (result);
}

//---------------------------------------------------------------
void CmtError::print ()
{
  /*
  TheError& e = TheError::instance ();

  cerr << "CMT> Error: " << get_error_name (e.get_code ()) << " : " << e.get_text () << endl;
  */
  if (CmtError::get_last_error_code () != CmtError::warning)
    CmtMessage::error (get_last_error ());
  else
    CmtMessage::warning (get_last_error ());
}

