//------------------------------------------------------------------------------
// emTmpFile.h
//
// Copyright (C) 2006-2008,2016 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emTmpFile_h
#define emTmpFile_h

#ifndef emModel_h
#include <emCore/emModel.h>
#endif

#ifndef emMiniIpc_h
#include <emCore/emMiniIpc.h>
#endif


//==============================================================================
//================================= emTmpFile ==================================
//==============================================================================

class emTmpFile : public emUncopyable {

public:

	// An object of this class can invent and hold the path of a temporary
	// file (or directory). The file (or directory tree) is deleted
	// automatically by the destructor. But the file is not created by this.

	emTmpFile();
		// Construct with an empty path.

	emTmpFile(emRootContext & rootContext, const char * postfix=NULL);
		// Like Setup.

	emTmpFile(const emString & customPath);
		// Like SetupCustomPath.

	~emTmpFile();
		// Like Discard.

	void Setup(emRootContext & rootContext, const char * postfix=NULL);
		// Invent and set a new path for a temporary file or directory,
		// which does not yet exist. Before that, Discard is called.
		//
		// *** DANGER ***
		// The path is invented via an emTmpFileMaster. Please read the
		// comments on emTmpFileMaster::InventPath.
		//
		// Arguments:
		//   rootContext - The root context. The context must live
		//                 longer than this emTmpFile object.
		//   postfix     - A postfix to be added to the end of the path
		//                 (file name suffix), or NULL.

	void SetupCustomPath(const emString & customPath);
		// Like Setup, but use the given path.

	const emString & GetPath() const;
		// Get the path of the temporary file.

	void Discard();
		// If the path is not empty, the file or directory tree is
		// deleted, and the path is set empty.

private:

	emString Path;
};

inline const emString & emTmpFile::GetPath() const
{
	return Path;
}


//==============================================================================
//============================== emTmpFileMaster ===============================
//==============================================================================

class emTmpFileMaster : public emModel {

public:

	// Class for a central instance inventing temporary file paths, and for
	// cleaning up.

	static emRef<emTmpFileMaster> Acquire(emRootContext & rootContext);
		// Acquire the emTmpFileMaster.

	emString InventPath(const char * postfix=NULL);
		// Invent a path for a temporary file or directory which does
		// not yet exist. The path ends with the given postfix, and it
		// lies in a special directory which is created solely for this
		// emTmpFileMaster. That directory and all its contents are
		// deleted on destruction of this emTmpFileMaster (= destruction
		// of root context). If that deletion does not take place
		// because of a program crash or so, the deletion is performed
		// at next construction of an emTmpFileMaster if it is a process
		// run by the same user on the same host. An emMiniIpcServer is
		// managed to find out whether the emTmpFileMaster for a
		// directory still exists.
		//
		// *** DANGER ***
		// If it ever fails to access the emMiniIpcServer of an existing
		// emTmpFileMaster from any process of the same user and host
		// for some reason, the files are deleted falsely. Therefore,
		// the temporary files should not be too valuable! And besides,
		// no one else should ever create a file in the directory, than
		// those who use a path invented with this method.

protected:

	emTmpFileMaster(emContext & context, const emString & name);

	virtual ~emTmpFileMaster();

private:

	static emString GetCommonPath();
	void DeleteDeadDirectories();
	void StartOwnDirectory();

	class IpcServerClass : public emMiniIpcServer {
	public:
		IpcServerClass(emScheduler & scheduler);
	protected:
		virtual void OnReception(int argc, const char * const argv[]);
	};

	IpcServerClass IpcServer;
	emString DirPath;
	unsigned FileNameCounter;
	static const char * DirNameEnding;
};


#endif
