//===- Diagnostic.cpp -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/LD/Diagnostic.h>
#include <llvm/Support/ErrorHandling.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/ADT/Twine.h>
#include <ctype.h>
#include <algorithm>

using namespace mcld;

//===----------------------------------------------------------------------===//
//  Diagnostic
Diagnostic::Diagnostic(DiagnosticEngine& pEngine)
  : m_Engine(pEngine) {
}

Diagnostic::~Diagnostic()
{
}

// format - format this diagnostic into string, subsituting the formal
// arguments. The result is appended at on the pOutStr.
void Diagnostic::format(std::string& pOutStr) const
{
  // we've not implemented DWARF LOC messages yet. So, keep pIsLoC false 
  llvm::StringRef desc = m_Engine.infoMap().getDescription(getID(), false);

  format(desc.begin(), desc.end(), pOutStr);
}

const char* Diagnostic::findMatch(char pVal,
                                  const char* pBegin, const char* pEnd ) const
{
  unsigned int depth = 0;
  for (; pBegin != pEnd; ++pBegin) {
    if (0 == depth && *pBegin == pVal)
      return pBegin;
    if (0 != depth && *pBegin == '}')
      --depth;

    if ('%' == *pBegin) {
      ++pBegin;
      if (pBegin == pEnd)
        break;

      if (!isdigit(*pBegin) && !ispunct(*pBegin)) {
        ++pBegin;
        while (pBegin != pEnd && !isdigit(*pBegin) && *pBegin != '{')
          ++pBegin;

        if (pBegin == pEnd)
          break;
        if ('{' == *pBegin)
          ++depth;
      }
    }
  } // end of for
  return pEnd;
}

// format - format the given formal string, subsituting the formal
// arguments. The result is appended at on the pOutStr.
void Diagnostic::format(const char* pBegin, const char* pEnd,
                        std::string& pOutStr) const
{
  const char* cur_char = pBegin;
  while (cur_char != pEnd) {
    if ('%' != *cur_char) {
      const char* new_end = std::find(cur_char, pEnd, '%');
      pOutStr.append(cur_char, new_end);
      cur_char = new_end;
      continue;
    }
    else if (ispunct(cur_char[1])) {
      pOutStr.push_back(cur_char[1]);  // %% -> %.
      cur_char += 2;
      continue;
    }

    // skip the %.
    ++cur_char;

    const char* modifier = NULL;
    size_t modifier_len = 0;

    // we get a modifier
    if (!isdigit(*cur_char)) {
      modifier = cur_char;
      while (*cur_char == '-' || (*cur_char >= 'a' && *cur_char <= 'z'))
        ++cur_char;
      modifier_len = cur_char - modifier;

      // we get an argument
      if ('{' == *cur_char) {
        ++cur_char; // skip '{'
        cur_char = findMatch('}', cur_char, pEnd);

        if (cur_char == pEnd) {
          // DIAG's format error
          llvm::report_fatal_error(llvm::Twine("Mismatched {} in the diagnostic: ") +
                                   llvm::Twine(getID()));
        }

        ++cur_char; // skip '}'
      }
    }
    if (!isdigit(*cur_char)) {
      llvm::report_fatal_error(llvm::Twine("In diagnostic: ") +
                               llvm::Twine(getID()) + llvm::Twine(": ") +
                               llvm::Twine(pBegin) +
                               llvm::Twine("\nNo given arugment number:\n"));
    }

    unsigned int arg_no = *cur_char - '0';
    ++cur_char; // skip argument number

    DiagnosticEngine::ArgumentKind kind = getArgKind(arg_no);
    switch (kind) {
      case DiagnosticEngine::ak_std_string: {
        if (0 != modifier_len) {
          llvm::report_fatal_error(llvm::Twine("In diagnostic: ") +
                                   llvm::Twine(getID()) +
                                   llvm::Twine(": ") + llvm::Twine(pBegin) +
                                   llvm::Twine("\nNo modifiers for strings yet\n"));
        }
        const std::string& str = getArgStdStr(arg_no);
        pOutStr.append(str.begin(), str.end());
        break;
      }
      case DiagnosticEngine::ak_c_string: {
        if (0 != modifier_len) {
          llvm::report_fatal_error(llvm::Twine("In diagnostic: ") +
                                   llvm::Twine(getID()) +
                                   llvm::Twine(": ") + llvm::Twine(pBegin) +
                                   llvm::Twine("\nNo modifiers for strings yet\n"));
        }
        const char* str = getArgCStr(arg_no);
        if (NULL == str)
          str = "(null)";
        pOutStr.append(str);
        break;
      }
      case DiagnosticEngine::ak_sint: {
        int val = getArgSInt(arg_no);
        llvm::raw_string_ostream(pOutStr) << val;
        break;
      }
      case DiagnosticEngine::ak_uint: {
        unsigned int val = getArgUInt(arg_no);
        llvm::raw_string_ostream(pOutStr) << val;
        break;
      }
      case DiagnosticEngine::ak_bool: {
        bool val = getArgBool(arg_no);
        if (val)
          pOutStr.append("true");
        else
          pOutStr.append("false");
        break;
      }
    } // end of switch
  } // end of while
}

