using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BestHTTP.Extensions
{
    /// 
    /// Used in string parsers. Its Value is optional.
    /// 
    public sealed class HeaderValue
    {
        #region Public Properties
        public string Key { get; set; }
        public string Value { get; set; }
        public List Options { get; set; }
        public bool HasValue { get { return !string.IsNullOrEmpty(this.Value); } }
        #endregion
        #region Constructors
        public HeaderValue()
        { }
        public HeaderValue(string key)
        {
            this.Key = key;
        }
        #endregion
        #region Public Helper Functions
        public void Parse(string headerStr, ref int pos)
        {
            ParseImplementation(headerStr, ref pos, true);
        }
        public bool TryGetOption(string key, out HeaderValue option)
        {
            option = null;
            if (Options == null || Options.Count == 0)
                return false;
            for (int i = 0; i < Options.Count; ++i)
                if (String.Equals(Options[i].Key, key, StringComparison.OrdinalIgnoreCase))
                {
                    option = Options[i];
                    return true;
                }
            return false;
        }
        #endregion
        #region Private Helper Functions
        private void ParseImplementation(string headerStr, ref int pos, bool isOptionIsAnOption)
        {
            string key = headerStr.Read(ref pos, (ch) => ch != ';' && ch != '=' && ch != ',', true);
            this.Key = key;
            char? skippedChar = headerStr.Peek(pos - 1);
            bool isValue = skippedChar == '=';
            bool isOption = isOptionIsAnOption && skippedChar == ';';
            while (skippedChar != null && isValue || isOption)
            {
                if (isValue)
                {
                    string value = headerStr.ReadPossibleQuotedText(ref pos);
                    this.Value = value;
                }
                else if (isOption)
                {
                    HeaderValue option = new HeaderValue();
                    option.ParseImplementation(headerStr, ref pos, false);
                    if (this.Options == null)
                        this.Options = new List();
                    this.Options.Add(option);
                }
                if (!isOptionIsAnOption)
                    return;
                skippedChar = headerStr.Peek(pos - 1);
                isValue = skippedChar == '=';
                isOption = isOptionIsAnOption && skippedChar == ';';
            }
        }
        #endregion
        #region Overrides
        public override string ToString()
        {
            if (!string.IsNullOrEmpty(Value))
                return String.Concat(Key, '=', Value);
            else
                return Key;
        }
        #endregion
    }
}