#include "common_sip_msrp.h"
#include <iostream>
#include <fstream>

namespace t3devlib { 
	  
  void PAInit()
  {
  }
  
  void SAInit()
  {
  }
  
  void CDInit()
  {
  }
  
  void PAReset()
  {
  }
  
  void SAReset()
  {
  }
  
  namespace gen {

void normalise_quoted_string (Charstring& cs, bool remove_quotes/* = false*/) throw (DecodeError)
{
	std::string result;

	//FIXME: how LWS shall be normalised ?
	
	const unsigned char* p   = cs.GetValueBin();
	const unsigned char* end = p + (cs.GetLength() / 8);

	if (remove_quotes)
	{
		if ((end - p) < 2)
			goto error_malformed;

		if ((*p++ != '"') | (*--end != '"'))
			goto error_malformed;
	}

	for ( ; p!=end ; p++)
	{
		switch (*p) {
		case '\r': //LWS
		case '\n':

		case ' ': //WSP
		case '\v':
		case '\t':
		case '\f':

		case 0x21: //!
			// plain text
			result += *p;
			break;

		case '\\':
			// escaped character
			p++;
			if ((p == end) || ((*p == '\r') | (*p == '\n'))) {
				// cannot be escaped
				// (should never happen since we checked it wit a regex before)
				DecodeError e (&cs);
				e.Msg() << "Invalid escaped sequence in quoted string: \\\\x" << std::hex << ((int) *p) << std::endl;
				throw e;
			}

			// valid escaped character
			result += *p;
			break;

		default:
			if ((*p >= 0x23) && (*p <= 0x7e))
			{
				// plain text
				result += *p;

			} else if (*p > 127) {
				// UTF-8 character
				//
				// FIXME: how to represent UTF-8 chars ? ('%xx' escape sequences are not used here)
				result += *p;

			} else {
				// non allowed character
				// (should never happen since we checked it wit a regex before)
				DecodeError e (&cs);
				e.Msg() << "Invalid character in quoted string: \\x" << std::hex << ((int) *p) << std::endl;
				throw e;
			}
		}
	}

	// replace the string with the quoted string
	{
		Bytestring& bs = cs;
		bs.SetValue (result);
	}
	return;

error_malformed:
	DecodeError e(&cs);
	e.Msg() << "Malformed quoted string: " << cs.GetValue() << endl;
	throw e;
}

void read_sp (Buffer & buffer, Variable* v) {
	static Regex reg_ws ("^[ \t]+");
	reg_ws.AssertMatch (buffer, v);
	int nPos = buffer.GetPosition() + reg_ws.GetMatchedLength();
	buffer.SetPosition (nPos);
}

bool detect_separator(Regex & reg_separator, Buffer & buffer)
{
	bool bRes;
	if (bRes = reg_separator.Match(buffer))
		reg_separator.MovePast(buffer);
	return bRes;
}

bool detect_semi(Buffer & buffer) throw (DecodeError)
{
	Regex reg_semi ("^" SIPREG_SEMI);
	return detect_separator(reg_semi, buffer);
}

bool detect_comma(Buffer & buffer)
{
	Regex reg_comma ("^" SIPREG_COMMA);
	return detect_separator(reg_comma, buffer);
}

}}
