/// <summary>
 /// Get a true/false response for an operation (i.e. delete something/update something)
 /// </summary>
 /// <param name="hasContent"></param>
 /// <param name="hasContentMatch"></param>
 /// <param name="terminator_action"></param>
 /// <returns></returns>
 public virtual bool SubmitRequest(bool hasContent, bool hasContentMatch, ResponseTerminatorAction terminator_action)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Perform the Request from the abstract class
 /// The different requestors will opt in and out
 /// of behaviors
 /// </summary>
 /// <returns></returns>
 public virtual string SubmitRequest(bool hasContent, ResponseTerminatorAction terminator_action)
 {
     //make sure the submit request is overridden.
     throw new NotImplementedException();
 }
 /// <summary>
 /// Get a string back from an alt request (i.e. post photo)
 /// </summary>
 /// <param name="hasContent"></param>
 /// <param name="terminator_action"></param>
 /// <param name="payload"></param>
 /// <param name="altContentType"></param>
 /// <returns></returns>
 public virtual string SubmitAltRequest(bool hasContent, ResponseTerminatorAction terminator_action, Stream payload, ContentType altContentType)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Submit a TCP Request
        /// </summary>
        /// <param name="hasContent">True if sending content</param>
        /// <param name="UseEntryTerminator">True if getting entry feed</param>
        /// <returns>string containing message data</returns>
        public override string SubmitAltRequest(bool hasContent, ResponseTerminatorAction terminator_action, Stream payload, ContentType contentType)
        {
            //Submit using TCP Protocol
            //if (hasContent)
            //{

            //}

            string header = BuildAltContentTypeHeader(contentType, (int)payload.Length);
            byte[] headerAsBytes = Encoding.ASCII.GetBytes(header);

            //create the alternate content for transmission

            TcpClient client = new TcpClient(Host, 443);
            Stream netStream = client.GetStream();
            SslStream sslStream = new SslStream(netStream);
            sslStream.AuthenticateAsClient(Host);
            sslStream.Write(headerAsBytes);
            if (payload.Length > 0)
            {
                byte[] altContent = new byte[payload.Length];
                payload.Read(altContent, 0, (int)payload.Length);
                payload.Close();

                sslStream.Write(altContent);
            }
            else if (hasContent)
            {
                byte[] contentAsBytes = Encoding.ASCII.GetBytes(ContentBody);
                sslStream.Write(contentAsBytes);
            }

            //read the stream
            StringBuilder messageData = new StringBuilder();
            if (terminator_action == ResponseTerminatorAction.READ_TO_END)
            {
                StreamReader reader = new StreamReader(sslStream);
                while (reader.Peek() > 0)
                {
                    string line = reader.ReadLine();
                    messageData.AppendLine(line);
                    if (line == null) break;
                }
            }
            else
            {
                byte[] buffer = new byte[2048];
                int bytes = -1;
                do
                {
                    bytes = sslStream.Read(buffer, 0, buffer.Length);
                    Decoder decoder = Encoding.UTF8.GetDecoder();
                    char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                    decoder.GetChars(buffer, 0, bytes, chars, 0);
                    messageData.Append(chars);
                    if (messageData.ToString().IndexOf(RESPONSE_TERMINATOR) > 0)
                    {
                        break;
                    }
                    else if (messageData.ToString().IndexOf(FEED_TERMINATOR) != -1 && terminator_action == ResponseTerminatorAction.FEED_TERMINATOR)
                    {
                        break;
                    }
                    else if (messageData.ToString().IndexOf(ENTRY_TERMINATOR) != -1 && terminator_action == ResponseTerminatorAction.ENTRY_TERMINATOR)
                    {
                        break;
                    }
                } while (bytes != 0);
            }
            sslStream.Close();

            //return the response as a string
            return messageData.ToString();
        }
        /// <summary>
        /// Submit a TCP request and get a boolean response
        /// </summary>
        /// <param name="hasContent"></param>
        /// <param name="hasContentMatch"></param>
        /// <param name="terminator_action"></param>
        /// <returns></returns>
        public override bool SubmitRequest(bool hasContent, bool hasContentMatch, ResponseTerminatorAction terminator_action)
        {
            string header = string.Empty;
            byte[] contentAsBytes = null;
            if (hasContentMatch)
            {
                if (HeaderContentType.Equals(ContentType.IF_MATCH_ALL))
                {
                    header = BuildIfMatchAllHeader();
                }
            }
            else
            {
                if (hasContent)
                {
                    contentAsBytes = Encoding.ASCII.GetBytes(ContentBody);
                    int contentLength = contentAsBytes.Length;
                    header = BuildHeader(hasContent, contentLength);
                }
                else
                {
                    header = BuildHeader(false, 0);
                }
            }
            byte[] headerAsBytes = Encoding.ASCII.GetBytes(header);

            TcpClient client = new TcpClient(Host, 443);
            Stream netStream = client.GetStream();
            SslStream sslStream = new SslStream(netStream);
            sslStream.AuthenticateAsClient(Host);
            sslStream.Write(headerAsBytes);

            if (null != contentAsBytes && contentAsBytes.Length > 0)
            {
                sslStream.Write(contentAsBytes);
            }

            StreamReader reader = new StreamReader(sslStream);
            bool success = false;
            while (reader.Peek() > 0)
            {
                string line = reader.ReadLine();
                if (terminator_action.Equals(ResponseTerminatorAction.CONTAINS_HTTP_1_1_200_OK))
                {
                    if (line.Contains("HTTP/1.1 200 OK"))
                    {
                        success = true;
                        break;
                    }
                }
                else if (terminator_action.Equals(ResponseTerminatorAction.CONTAINS_HTTP_1_1_201_CREATED))
                {
                    if (line.ToUpper().Contains("HTTP/1.1 201 CREATED"))
                    {
                        success = true;
                        break;
                    }
                }
                if (line == null)
                {
                    break;
                }
            }
            return success;
        }
        /// <summary>
        /// Submit a TCP Request
        /// </summary>
        /// <param name="hasContent">True if sending content</param>
        /// <param name="UseEntryTerminator">True if getting entry feed</param>
        /// <returns>string containing message data</returns>
        public override string SubmitRequest(bool hasContent, ResponseTerminatorAction terminator_action)
        {
            byte[] contentAsBytes = null;
            int contentLength = 0;
            //Submit using TCP Protocol
            if (hasContent)
            {
                contentAsBytes = Encoding.ASCII.GetBytes(ContentBody);
                contentLength = contentAsBytes.Length;
            }

            string header = BuildHeader(hasContent, contentLength);
            byte[] headerAsBytes = Encoding.ASCII.GetBytes(header);

            TcpClient client = new TcpClient(Host, 443);
            Stream netStream = client.GetStream();
            SslStream sslStream = new SslStream(netStream);
            sslStream.AuthenticateAsClient(Host);
            sslStream.Write(headerAsBytes);
            if (hasContent)
            {
                sslStream.Write(contentAsBytes);
            }

            //read the stream
            StringBuilder messageData = new StringBuilder();
            if (terminator_action == ResponseTerminatorAction.READ_TO_END)
            {
                StreamReader reader = new StreamReader(sslStream);
                while (reader.Peek() > 0)
                {
                    string line = reader.ReadLine();
                    messageData.AppendLine(line);
                    if (line == null) break;
                }
            }
            else
            {
                byte[] buffer = new byte[2048];
                int bytes = -1;
                do
                {
                    bytes = sslStream.Read(buffer, 0, buffer.Length);
                    Decoder decoder = Encoding.UTF8.GetDecoder();
                    char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                    decoder.GetChars(buffer, 0, bytes, chars, 0);
                    messageData.Append(chars);
                    if (messageData.ToString().IndexOf(RESPONSE_TERMINATOR) > 0)
                    {
                        break;
                    }
                    else if (messageData.ToString().IndexOf(FEED_TERMINATOR) != -1 && terminator_action == ResponseTerminatorAction.FEED_TERMINATOR)
                    {
                        break;
                    }
                    else if (messageData.ToString().IndexOf(ENTRY_TERMINATOR) != -1 && terminator_action == ResponseTerminatorAction.ENTRY_TERMINATOR)
                    {
                        break;
                    }
                    else if (messageData.ToString().ToUpper().IndexOf("FORBIDDEN") != -1)
                    {
                        break;
                    }
                    else if (messageData.ToString().ToUpper().IndexOf("NOT FOUND") != -1)
                    {
                        break;
                    }
                } while (bytes != 0);
            }
            sslStream.Close();

            //return the response as a string
            return messageData.ToString();
        }