using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace Rssdp.Infrastructure
{
	/// 
	/// Parses a string into a  or throws an exception.
	/// 
	public sealed class HttpResponseParser : HttpParserBase 
	{
		#region Fields & Constants
		private readonly string[] ContentHeaderNames = new string[]
				{
					"Allow", "Content-Disposition", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified"
				};
		#endregion
		#region Public Methods
		/// 
		/// Parses the specified data into a  instance.
		/// 
		/// A string containing the data to parse.
		/// A  instance containing the parsed data.
		public override HttpResponseMessage Parse(string data)
		{
			System.Net.Http.HttpResponseMessage retVal = null;
			try
			{
				retVal = new System.Net.Http.HttpResponseMessage();
				Parse(retVal, retVal.Headers, data);
				return retVal;
			}
			catch
			{
				if (retVal != null)
					retVal.Dispose();
				throw;
			}
		}
		#endregion
		#region Overrides Methods
		/// 
		/// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false).
		/// 
		/// A string containing the name of the header to return the type of.
		/// A boolean, true if th specified header relates to HTTP content, otherwise false.
		protected override bool IsContentHeader(string headerName)
		{
			return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase);
		}
		/// 
		/// Used to parse the first line of an HTTP request or response and assign the values to the appropriate properties on the .
		/// 
		/// The first line of the HTTP message to be parsed.
		/// Either a  or  to assign the parsed values to.
		protected override void ParseStatusLine(string data, HttpResponseMessage message)
		{
			if (data == null) throw new ArgumentNullException("data");
			if (message == null) throw new ArgumentNullException("message");
			var parts = data.Split(' ');
			if (parts.Length < 2) throw new ArgumentException("data status line is invalid. Insufficient status parts.", "data");
			message.Version = ParseHttpVersion(parts[0].Trim());
			int statusCode = -1;
			if (!Int32.TryParse(parts[1].Trim(), out statusCode))
				throw new ArgumentException("data status line is invalid. Status code is not a valid integer.", "data");
			message.StatusCode = (HttpStatusCode)statusCode;
            if (parts.Length >= 3)
            {
                message.ReasonPhrase = parts[2].Trim();
            }
        }
		#endregion
	}
}