#ifndef MAINTENANCE_H_
#define MAINTENANCE_H_

#include "config.h"
#include "meta.h"
#include "sockio.h"
#include "acbuf.h"

#ifdef DEBUG
#define MTLOGDEBUG(x) { SendFmt()<< x << "<br>\n"; }
#define MTLOGASSERT(x, y) {if(!(x)) SendFmt()<< "<font color=red><b>" << y << "</b></font><br>\n";}
//#define MTLOGVERIFY(x, y) MTLOGASSERT(x, y)
#else
#define MTLOGASSERT(x, y) {}
#define MTLOGDEBUG(x) {}
//#define MTLOGVERIFY(x, y) x
#endif

class tWUIPage
{
public:
	/*!
	 *  @brief Main execution method for maintenance tasks.
	 */
	virtual void Run(const mstring &cmd)=0;

	tWUIPage(int fd);
	virtual ~tWUIPage();

protected:
	inline void SendChunk(const mstring &x) { SendChunk(x.data(), x.size()); }

	inline void SendChunk(const tSS &x){ SendChunk(x.data(), x.length()); }
	virtual void SendChunk(const char *data, size_t size);
	inline void SendChunk(const char *x) { SendChunk(x, x?strlen(x):0); }

	bool SendRawData(const char *data, size_t len, int flags);
	virtual void EndTransfer();
	mstring & GetHostname();
	//void SendDecoration(bool bBegin, const char *szDecoFile=NULL);
	void SendChunkedPageHeader(const char *httpcode=NULL, const char *mimetype=NULL);
	int m_reportFD;
	const char *m_szDecoFile;
private:
	tWUIPage(const tWUIPage&);
	tWUIPage& operator=(const tWUIPage&);
	mstring m_sHostname;

public:

	// dirty little helper to create an object which shares memory with its previous/future
	// instances. Some methods are inlined in order to skip unnecessary dtor calls.
	class tFmtSendObj: public tSS
	{
	public:
		inline tFmtSendObj(tWUIPage &p) : m_parent(p)
		{
			m_buf = m_parent.m_fmtBuf;
			m_nCapacity = m_parent.m_fmtSize;
		}
		inline ~tFmtSendObj()
		{
			if (!empty())
			{
				m_parent.SendChunk(data(), length());
				m_parent.m_fmtBuf = m_buf;
				m_parent.m_fmtSize = m_nCapacity;
				m_buf = NULL;
				m_nCapacity = 0;
			}
		}
	private:
		tWUIPage &m_parent;
		tFmtSendObj operator=(const tWUIPage::tFmtSendObj&);
	};

#define SendFmt() tFmtSendObj(*this)
	char *m_fmtBuf;
	size_t m_fmtSize;

};

void DispatchAndRunMaintTask(cmstring &cmd, int fd, const char *auth);

#endif /*MAINTENANCE_H_*/
