using System.Diagnostics;
using System.Globalization;

namespace Ryujinx.HLE.Debugger
{
    class StringStream
    {
        private readonly string Data;
        private int Position;

        public StringStream(string s)
        {
            Data = s;
        }

        public char ReadChar()
        {
            return Data[Position++];
        }

        public string ReadUntil(char needle)
        {
            int needlePos = Data.IndexOf(needle, Position);

            if (needlePos == -1)
            {
                needlePos = Data.Length;
            }

            string result = Data.Substring(Position, needlePos - Position);
            Position = needlePos + 1;
            return result;
        }

        public string ReadLength(int len)
        {
            string result = Data.Substring(Position, len);
            Position += len;
            return result;
        }

        public string ReadRemaining()
        {
            string result = Data.Substring(Position);
            Position = Data.Length;
            return result;
        }

        public ulong ReadRemainingAsHex()
        {
            return ulong.Parse(ReadRemaining(), NumberStyles.HexNumber);
        }

        public ulong ReadUntilAsHex(char needle)
        {
            return ulong.Parse(ReadUntil(needle), NumberStyles.HexNumber);
        }

        public ulong ReadLengthAsHex(int len)
        {
            return ulong.Parse(ReadLength(len), NumberStyles.HexNumber);
        }

        public ulong ReadLengthAsLEHex(int len)
        {
            Debug.Assert(len % 2 == 0);

            ulong result = 0;
            int pos = 0;
            while (pos < len)
            {
                result += ReadLengthAsHex(2) << (4 * pos);
                pos += 2;
            }
            return result;
        }

        public ulong? ReadRemainingAsThreadUid()
        {
            string s = ReadRemaining();
            return s == "-1" ? null : ulong.Parse(s, NumberStyles.HexNumber);
        }

        public bool ConsumePrefix(string prefix)
        {
            if (Data.Substring(Position).StartsWith(prefix))
            {
                Position += prefix.Length;
                return true;
            }
            return false;
        }

        public bool ConsumeRemaining(string match)
        {
            if (Data.Substring(Position) == match)
            {
                Position += match.Length;
                return true;
            }
            return false;
        }

        public bool IsEmpty()
        {
            return Position >= Data.Length;
        }
    }
}
