/*
 * @(#)Server.h
 *
 * This file is part of webCDwriter - Network CD Writing.
 *
 * Copyright (C) 1999-2003 Jörg P. M. Haeger
 *
 * webCDwriter is free software. See CDWserver.cpp for details.
 */

#ifndef SERVER_H
#define SERVER_H

#include <time.h>
#include "CDstate.h"
#include "Options.h"

enum writerStates { idle, reserved, blanking,
	mkisofs, writing, fixating, verifying, reading };

struct Writer {
	int fifoPercent;
	class Server *owner;
	enum writerStates state;
	int percent, reservedUntil;

	Writer() {
		fifoPercent = 100;
		owner = NULL;
		state = idle;
		percent = 0;
		reservedUntil = 0;
	}
};

/*
 * Implementation of a server process.
 *
 * @version 20030311
 * @author Jörg P. M. Haeger
 */
class Server {
	public: static const char
		errorInCommand[], hint[], hintPercentDone[], info[], unknown[];
	protected: static int hasDVDSupport;

public:
	Server(int socket);
	~Server();
	static int getActiveServersNum() { return activeServersNum; }
	const char *getClientIP() { return clientIP; }
	const char *getClientUserName() { return clientUserName; }
	int getNo() { return serverNo; }
	static enum writerStates getReaderStatus(int no)
		{ return readers[no].state; }
	static int getWriterFifoPercent(int writerNo)
		{ return writers[writerNo].fifoPercent; }
	static Server *getWriterOwner(int writerNo)
		{ return writers[writerNo].owner; }
	static int getWriterPercent(int writerNo)
		{ return writers[writerNo].percent; }
	static int getWriterReservedUntil(int writerNo)
		{ return writers[writerNo].reservedUntil; }
	static enum writerStates getWriterStatus(int writerNo)
		{ return writers[writerNo].state; }
	static void initStatic();
	static void initStatic2();
	void run();
	static void terminate();
	int waitForService(class Queue *queue, int toRank);

private:
	void addArgs(Process &p, const char *args);
	void blank(char *cmdStr);
	void burnCopy();
	void burnSession();
	protected: virtual void checkDVDSupport() {
		throw new Exception(
			"This version of CDWserver has no DVD+RW support!");
	}
	void checkFileName(const char *fileName);
	void checkLoggedIn();
	void checkOpenSession();
	void eject();
	void ejectReader();
	void errorToClient(const char *format, ...);
	void executeCmd();
	protected: const char *getNewLogFileName(char *str);
	void load();
	void logCDstate(const char *resultStr);
	void logConnection();
	void logSession(const char *typeStr, const char *resultStr);
	void nextCmd();
	int noDisc(int trayOpenIfNoDisc = 0);
	void readATIP();
	void readMultiSessionInfo();
	void readTOC();
	char *removeEscChars(char *str);
	void reserveReader();
	void reserveWriter();
	void resetImageFile();
	void run_cdrdaoCopy();
	void run_cdrecord();
	void run_cdrecord2();
	protected: virtual void run_cdrecordBlank(const char *modeStr);
	void run_cdrecordCopy();
	protected: virtual void run_growisofs() { }
	void run_mkisofs();
	void saveLineStr();
	void showWaitForDiscMsg();
	static const char *spaceToEsc(const char *str);
	void start_mkisofs(Process &p);
	void successToClient(const char *format, ...);
	static char *timeToDigits(time_t t, char *str, size_t size);
	static char *timeToShortString(time_t t, char *str, size_t size);
	static char *timeToString(time_t t, char *str, size_t size);
	void toClient(const char *type, const char *format, ...);
	void toClient(const char *type, String &str);
	void verify();
	int waitForDisc();
	void writeImageToRawDevice();

	static int activeServersNum;
	static int nextServerNo;
	static class Queue *readerQueue;
	static Writer *readers;
	static class Queue *writerQueue;
	static Writer *writers;

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

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

	// modes
	int
		modeShowCdrecord, modeShowMkisofs;

	struct Options options;
	struct CDstate CDstate;
	class Session *session;
	const char *tmpSessionID;
	FILE *project;

	int quit;
};

#endif
