using System;
using System.Collections;
using System.Text;
using sscs.communication;
using sscs.common;
using sscs.verbs;
using sscs.constants;

class AppHandler
{
    //Data
    private IPCChannel clientChannel;

    //Methods
    internal AppHandler(IPCChannel ipcChannel)
    {
        clientChannel = ipcChannel;
        CSSSLogger.ExecutionTrace(this);
    }

    ~AppHandler()
    {
        CSSSLogger.ExecutionTrace(this);
    }

    /* Starts servicing the application. This is called as soon
     * as a new client connection is established.
     */
    internal int ServiceApp()
    {
        SSVerb verb = null; 
        CSSSLogger.ExecutionTrace(this);

        while(true)
        {
            byte[] buf = null;

            try
            {
                buf = clientChannel.Read();
                if( null == buf )
                {
                    return RetCodes.SUCCESS;
                }
                RequestParser reqParser = new RequestParser();
                verb = reqParser.ParseRequest(buf);
                CSSSLogger.logbreak();
                CSSSLogger.DbgLog("SSCS going to sevice a :: ** " + verb.GetVerbName()  + "  **");

                UserIdentifier userId = clientChannel.GetIPCChannelUserId();

                if(null == userId)
                {
                    CSSSLogger.log(ConstStrings.DEBUG, "In " + CSSSLogger.GetExecutionPath(this) + " a null user is obtained.");
                    return RetCodes.FAILURE;
 
                }

                buf = verb.ProcessRequest(userId);
                if ( buf != null)
                {
                    int retVal = clientChannel.Write(buf);
                    if(retVal < 0)
                    {
                        CSSSLogger.DbgLog("Write failed");
                        return RetCodes.FAILURE;
                    }
                }
                else
                {
                    //There must always be something written back to client.
                    return RetCodes.FAILURE;
                }
            }
            catch(CommunicationException e)
            {
                CSSSLogger.ExpLog(e.ToString());
                throw e;
            }
            catch(FormatException e)
            {
                CSSSLogger.ExpLog(e.ToString());
                throw e;
            }
            catch(Exception e)
            {
                CSSSLogger.ExpLog(e.ToString());
                throw e;
            }

            /* TBD define verb specific heirarchy of exceptions  catch
             * (Some processing problem)
             */
                 
            finally
            {
                CSSSLogger.DbgLog("SSCS finished processing a SS Verb :: ** " + verb.GetVerbName() + "  **");
                CSSSLogger.logbreak();
            }
        }
    }
}