using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InABox.Core
{
    /// <summary>
    /// An editor for a field of type <see langword="string"/>, which saves a list of "tags", with a <see cref="Prefix"/> and <see cref="Separator"/>.
    /// </summary>
    /// <remarks>
    /// The separator really is a suffix, because it is appended even to the last tag in the list. For example, with the default prefix and separator,
    /// the tags "foo", "bar" and "baz" would save as the string <c>"#foo;#bar;#baz"</c>. This allows for filtering easily with
    /// <see cref="Operator.Contains"/> filters.
    /// </remarks>
    public class TagsEditor : BaseEditor
    {
        public string Prefix { get; set; }

        public string Separator { get; set; }

        public TagsEditor(string prefix = "#", string separator = ";")
        {
            Prefix = prefix;
            Separator = separator;
        }

        public IEnumerable<string> ReadTags(string tags)
        {
            int idx = 0;
            while (idx < tags.Length)
            {
                var nextIdx = tags.IndexOf(Prefix, idx);
                if(nextIdx == -1)
                {
                    nextIdx = idx;
                }
                else
                {
                    nextIdx += 1;
                }
                var endIdx = tags.IndexOf(Separator, nextIdx);
                if(endIdx == -1)
                {
                    yield return tags[nextIdx..];
                    yield break;
                }
                else
                {
                    yield return tags[nextIdx..(endIdx - 1)];
                    idx = endIdx + 1;
                }
            }
        }
        public string WriteTags(IEnumerable<string> tags)
        {
            return string.Join("", tags.Select(x => $"{Prefix}{x}{Separator}"));
        }

        protected override BaseEditor DoClone()
        {
            return new TagsEditor(Prefix, Separator);
        }
    }
}
