
#ifndef SERVER_H
#define SERVER_H

#include <time.h>
#include "Cdrecord.h"

enum writerStates { idle, reserved, blanking, mkisofs, writing };

class Server
{
public:
	Server(int socket);
	~Server();
	static int getActiveServersNum() { return activeServersNum; }
	const char *getClientIP() { return clientIP; }
	const char *getClientUserName() { return clientUserName; }
	static int getFifoPercent() { return fifoPercent; }
	static Server *getWriterOwner() { return writerOwner; }
	static int getWriterPercent() { return writerPercent; }
	static int getWriterReservedUntil() { return writerReservedUntil; }
	static enum writerStates getWriterStatus() { return writerStatus; }
	static void initStatic();
	static void initStatic2();
	void run();
	static void terminate();
	int waitForService(class Queue *queue, int toRank);

private:
	void addCdrecordArgs(Process &p);
	void blank(char *cmdStr);
	void burnSession(char *cmdStr);
	void checkOpenSession();
	void eject();
	void errorToClient(const char *format, ...);
	void executeCmd();
	const char *getNewLogFileName(char *str);
	void load();
	void logCDstatus(const char *resultStr);
	void logConnection();
	void logSession(const char *typeStr, const char *resultStr);
	void nextCmd();
	int noDisc(int trayOpenIfNoDisc = 0);
	void readATIP();
	void readTOC();
	void resetImageFile();
	void run_cdrecord();
	void run_cdrecord2();
	void run_cdrecordBlank(const char *modeStr);
	void run_mkisofs();
	void saveLineStr();
	void showWaitForDiscMsg();
	void start_mkisofs(Process &p);
	void successToClient(const char *format, ...);
	void toClient(const char *type, const char *format, ...);
	int waitForDisc();

	static int activeServersNum;
	static int nextServerNo;
	static Server *writerOwner;
	static class Queue *writerQueue;
	static enum writerStates writerStatus;
	static int fifoPercent, writerPercent, writerReservedUntil;

	int serverNo;
	time_t connectionT0, sessionT0, sessionT1, burnT0;
	int sock;
	FILE *inStream;
	char lineStr[1024];
	int logFilesNum;

	// states
	int bytesReceived;
	static int configError;
	int openCommands, isOffline;
	const char
		*clientIP,
		*clientSystemName, *clientSystemVersion,
		*clientUserID, *clientUserName,
		*userID, *userPassword, *userID2;

	// modes
	int
		modeShowCdrecord, modeShowMkisofs;

	struct Options
	{
		int protocolVersion;
		int blankTOC;
		const char *bootImage;
		int closeCD;
		int HFS;
		int joliet;
		int laserOff;
		int burnOffline;
		int rockRidge;
		int speed;
		const char *volumeID;

		Options()
		{
			protocolVersion = 1;
			bootImage = NULL;
			volumeID = NULL;
			reset();
		}

		void reset()
		{
			if (protocolVersion == 1)
			{
				closeCD = 1;
				joliet = 1;
				rockRidge = 1;
			}
			else
			{
				closeCD = 0;
				joliet = 0;
				rockRidge = 0;
			}
			blankTOC = 0;
			if (bootImage != NULL)
			{
				delete[] bootImage;
				bootImage = NULL;
			}
			burnOffline = 0;
			HFS = 0;
			laserOff = 0;
			speed = config.getDefaultSpeed();
			if (volumeID != NULL)
			{
				delete[] volumeID;
				volumeID = NULL;
			}
		}
	} options;

	struct CDstatus CDstatus;
	class Session *session;

	int quit;
};

#endif
