/***********************************************************************
 * 
 *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library 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
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 ***********************************************************************/

using System;
using System.Threading;
using System.IO;

using AppModule.InterProcessComm;
using AppModule.NamedPipes;

namespace sscs.communication.win {

	public sealed class ServerNamedPipe : IDisposable {
		internal Thread PipeThread;
		internal ServerPipeConnection PipeConnection;
		internal bool Listen = true;
		internal DateTime LastAction;
		private bool disposed = false;

		private void PipeListener() {
			CheckIfDisposed();
			try {
				Listen = true;				
				while (Listen) {
					LastAction = DateTime.Now;

					// Service Client (new code)
					IPCChannel ipcChannel = IPCChannel.Create(PipeConnection);
					AppHandler appHandler = new AppHandler(ipcChannel);

					try
					{
						int retVal = appHandler.ServiceApp();
					} 
					catch(Exception)
					{						
						ipcChannel.Close();
					}

					LastAction = DateTime.Now;
					PipeConnection.Disconnect();
					if (Listen) {
						Connect();
					}
					WinCommunication.PipeManager.WakeUp();
				}
			} 
			catch (System.Threading.ThreadAbortException) { }
			catch (System.Threading.ThreadStateException) { }
			catch (Exception) { 
				// Log exception
			
			}
			finally {
				this.Close();
			}
		}
		internal void Connect() {
			CheckIfDisposed();
			PipeConnection.Connect();
		}
		internal void Close() {
			CheckIfDisposed();
			this.Listen = false;
			WinCommunication.PipeManager.RemoveServerChannel(this.PipeConnection.NativeHandle);
			this.Dispose();
		}
		internal void Start() {
			CheckIfDisposed();
			PipeThread.Start();
		}
		private void CheckIfDisposed() {
			if(this.disposed) {
				throw new ObjectDisposedException("ServerNamedPipe");
			}
		}
		public void Dispose() {
			Dispose(true);
			GC.SuppressFinalize(this);
		}
		private void Dispose(bool disposing) {
			if(!this.disposed) {
				PipeConnection.Dispose();
				if (PipeThread != null) {
					try {
						PipeThread.Abort();
					} 
					catch (System.Threading.ThreadAbortException) { }
					catch (System.Threading.ThreadStateException) { }
					catch (Exception) {
						// Log exception
					}
				}
			}
			disposed = true;         
		}
		~ServerNamedPipe() {
			Dispose(false);
		}
		internal ServerNamedPipe(string name, uint outBuffer, uint inBuffer, int maxReadBytes) {
			PipeConnection = new ServerPipeConnection(name, outBuffer, inBuffer, maxReadBytes, false);
			PipeThread = new Thread(new ThreadStart(PipeListener));
			PipeThread.IsBackground = true;
			PipeThread.Name = "Pipe Thread " + this.PipeConnection.NativeHandle.ToString();
			LastAction = DateTime.Now;
		}
	}
}