//                           UNCLASSIFIED
/*-------------------------------------------------------------------------
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
COMPANY.

THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
GOVERNMENT.

UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/

using Raytheon.Common;
using System;
using System.Collections.Generic;

namespace Raytheon.Instruments
{
   /// <summary>
   /// Parses out messages that go between the VRSUI and the Test Controller
   /// This class is meant to be used by both the test controller and the VRSUI, so it parses out messages that target either of those systems
   /// </summary>
   internal class VrsMsgParser : IMsgParser
   {
      #region PrivateClassMembers
      private List<uint> _messageList;
      private AutomationMessageHeader _header;
      #endregion

      #region PublicClassFunctions

      /// <summary>
      /// The constructor
      /// </summary>
      public VrsMsgParser()
      {
         _messageList = new List<uint>();
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_CONNECT_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_CONNECT_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_GRAB_VIDEO_TO_DISK_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_GRAB_VIDEO_TO_DISK_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_GRAB_TO_DISK_COMPLETE_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_SHOW_LIVE_VIDEO_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_SHOW_LIVE_VIDEO_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_STOP_LIVE_VIDEO_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_STOP_LIVE_VIDEO_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_MOVE_FILE_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_MOVE_FILE_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_QUERY_HARD_DRIVE_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_QUERY_HARD_DRIVE_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_ADD_ATTRIBUTES_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_ADD_ATTRIBUTES_RSP);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_DISCONNECT_CMD);
         _messageList.Add((uint)VrsAutomationMsgIds.VRS_DISCONNECT_RSP);

         _header = new AutomationMessageHeader();
      }

      /// <summary>
      /// Search the data buffer for the next valid message
      /// </summary>
      /// <param name="pData">The data buffer to search</param>
      /// <param name="numBytesInPdata">The number of bytes in pData</param>
      /// <param name="bytesToRemove">The number of bytes to remove from the buffer</param>
      /// <param name="messageId">the msg id that this function finds</param>
      /// <param name="errorCode">The error that this functions finds</param>
      /// <returns></returns>
      public bool Run(IntPtr pData, uint numBytesInPdata, ref uint bytesToRemove, ref uint messageId, ref uint errorCode)
      {
         // default error code to 0. Not used in this parser
         errorCode = 0;

         // check to see if we have enough data for at least a header
         if (numBytesInPdata < AutomationMessageHeader.HEADER_EXPECTED_SIZE)
         {
            ErrorLogger.Instance().Write("VrsMsgParser::run() - not enough data in the buffer to form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes", ErrorLogger.LogLevel.INFO);
            bytesToRemove = 0;
            return false;
         }

         // create and parse header
         _header.Parse(pData);

         uint totalMsgSize = _header.GetEntireMsgLength();

         // do we have this message in our messageSizeMap_ dictionary?
         if (_messageList.Contains(_header.GetMessageId()) == false)
         {
            string msg = "VrsMsgParser::run() - unknown id received: " + Convert.ToString(_header.GetMessageId());
            ErrorLogger.Instance().Write(msg, ErrorLogger.LogLevel.ERROR);
            bytesToRemove = totalMsgSize; // move on to next message
            return false;
         }

         // do we have enough data to make the complete message
         if (numBytesInPdata < totalMsgSize)
         {
            // need to wait for more data
            bytesToRemove = 0;
            return false;
         }

         // everything has checked out.
         bytesToRemove = totalMsgSize;
         messageId = _header.GetMessageId();
         return true;
      }
      #endregion
   }
}
