using System.Globalization;
using System.Text;

namespace SharpChat;
public static class StringExtensions {
    public static byte[] GetUtf8Bytes(this string str) {
        return Encoding.UTF8.GetBytes(str);
    }

    public static byte[] GetUtf8Bytes(this string str, int index, int count) {
        return Encoding.UTF8.GetBytes(str, index, count);
    }

    public static int CountUtf8Bytes(this string str) {
        return Encoding.UTF8.GetByteCount(str);
    }

    public static int CountUnicodeGraphemes(this string str) {
        return new StringInfo(str).LengthInTextElements;
    }

    public static bool SlowUtf8Equals(this string str, string other) {
        return str.GetUtf8Bytes().SlowEquals(other.GetUtf8Bytes());
    }

    public static string TruncateIfTooLong(this string str, int? maxGraphemes = null, int? maxBytes = null) {
        StringInfo info = new(str);

        if(maxGraphemes.HasValue) {
            if(maxGraphemes.Value == 0)
                return string.Empty;
            if(maxGraphemes.Value < 0)
                throw new ArgumentException("Maximum Unicode Grapheme Cluster count must be a positive integer.", nameof(maxGraphemes));

            if(info.LengthInTextElements > maxGraphemes.Value)
                return info.SubstringByTextElements(0, maxGraphemes.Value);
        }

        if(maxBytes.HasValue) {
            if(maxBytes.Value == 0)
                return string.Empty;
            if(maxBytes.Value < 0)
                throw new ArgumentException("Maximum bytes must be a positive integer.", nameof(maxBytes));

            if(str.CountUtf8Bytes() > maxBytes.Value)
                return maxGraphemes.HasValue
                    ? info.SubstringByTextElements(0, Math.Min(info.LengthInTextElements, maxGraphemes.Value))
                    : str.GetUtf8Bytes(0, maxBytes.Value).GetUtf8String();
        }

        return str;
    }
}