// ConfigFile.cpp

#include "ConfigFile.h"


using std::string;

ConfigFile::ConfigFile (
string filename,
string delimiter,
string comment,
string sentry
)
  : myDelimiter (delimiter),
    myComment (comment),
    mySentry (sentry)
{
  // Construct a ConfigFile, getting keys and values from given file

  std::ifstream in (filename.c_str ());

  if (!in) throw file_not_found (filename);

  in >> (*this);
}


ConfigFile::ConfigFile ()
  : myDelimiter (string (1,'=')),
    myComment (string (1,'#'))
{
  // Construct a ConfigFile without a file; empty
}


void
ConfigFile::remove (const string& key)
{
  // Remove key and its value
  myContents.erase (myContents.find (key));
  return;
}


bool
ConfigFile::keyExists (const string& key) const
{
  // Indicate whether key is found
  mapci p = myContents.find (key);

  return (p != myContents.end ());
}


/* static */
void
ConfigFile::trim (string& s)
{
  // Remove leading and trailing whitespace
  static const char whitespace[] = " \n\t\v\r\f";

  s.erase (0, s.find_first_not_of (whitespace));
  s.erase (s.find_last_not_of (whitespace) + 1U);
}


std::ostream&
operator<< (std::ostream& os, const ConfigFile& cf)
{
  // Save a ConfigFile to os
  for (ConfigFile::mapci p = cf.myContents.begin ();
       p != cf.myContents.end ();
       ++p)
  {
    os << p->first << " " << cf.myDelimiter << " ";
    os << p->second << std::endl;
  }
  return os;
}


std::istream&
operator>> (std::istream& is, ConfigFile& cf)
{
  // Load a ConfigFile from is
  // Read in keys and values, keeping internal whitespace
  typedef string::size_type pos;
  const string              &delim  = cf.myDelimiter; // separator
  const string              &comm   = cf.myComment;   // comment
  const string              &sentry = cf.mySentry;    // end of file sentry
  const pos                 skip = delim.length ();   // length of separator

  string nextline = "";  // might need to read ahead to see where value ends

  while (is  ||  nextline.length () > 0)
  {
    // Read an entire line at a time
    string line;

    if (nextline.length () > 0)
    {
      line = nextline;  // we read ahead; use it now
      nextline = "";
    }
    else
    {
      std::getline (is, line);
    }

    // Ignore comments
    line = line.substr (0, line.find (comm));

    // Check for end of file sentry
    if (sentry != ""  &&  line.find (sentry) != string::npos) return is;

    // Parse the line if it contains a delimiter
    pos delimPos = line.find (delim);
    if (delimPos < string::npos)
    {
      // Extract the key
      string key = line.substr (0, delimPos);
      line.replace (0, delimPos+skip, "");

      // See if value continues on the next line
      // Stop at blank line, next line with a key, end of stream,
      // or end of file sentry
      bool terminate = false;
      while (!terminate  &&  is)
      {
        std::getline (is, nextline);
        terminate = true;

        string nlcopy = nextline;
        ConfigFile::trim (nlcopy);
        if (nlcopy == "") continue;

        nextline = nextline.substr (0, nextline.find (comm));
        if (nextline.find (delim) != string::npos)
          continue;
        if (sentry != ""  &&  nextline.find (sentry) != string::npos)
          continue;

        nlcopy = nextline;
        ConfigFile::trim (nlcopy);
        if (nlcopy != "") line += "\n";
        line += nextline;
        terminate = false;
      }

      // Store key and value
      ConfigFile::trim (key);
      ConfigFile::trim (line);
      cf.myContents[key] = line;  // overwrites if key is repeated
    }
  }

  return is;
}
