#include <iostream>
#include <string>
#include <ostream>
#include <istream>

#include <bobcat/exception>
#include <bobcat/memorystream>

using namespace std;
using namespace FBB;

int main(int argc, char **argv)
{
    MemoryStream ms;

    char ch = 'h';
    string cmd;

    while (true)
    {
        ios::off_type offset;

        switch (ch)
        {
            case 'h':
                cout <<
                    "\n"
                    " b     open a MemoryStream for 10k\n"
                    " h     this info\n"
                    " i     show info about the memory stream\n"
                    " o     show the current absolute offset\n"
                    " q     quit\n"
                    " s <x> seek (abs) offset x\n"
                    " x     extract the next line from the current offset\n"
                    " <     insert lines (until empty) at the current "
                                                            "offset\n"
                    " >     extract lines (until EOF) from the current "
                                                            "offset\n";
            break;

            case 'b':
                ms.open("10k", true);
            [[fallthrough]];

            case 'i':
                ms.info(cout);
            break;

            case 'o':
                cout << ms.seekg(0, ios::cur).tellg() << '\n';
            break;

            case 'q':
            return 0;

            case 's':
            {
                size_t offset;
                cin >> offset;
                cout << "tellg: " << ms.seekg(offset).tellg() << '\n';
            }
            break;

            case 'x':
            {
                string line;
                if (getline(ms, line))
                    cout << line << '\n';
                else
                {
                    cout << "No lines available\n";
                    ms.clear();
                }
            }
            break;

            case '<':
            {
                cin.ignore(100, '\n');
                while (true)
                {
                    string line;
                    getline(cin, line);
                    if (line.empty())
                        break;
                    ms << line << endl;
                }
            }
            break;

            case '>':
            {
                string line;
                while (getline(ms, line))
                    cout << line << '\n';
                ms.clear();
                ms.seekg(0, ios::end);
            }
            break;
            default:
                cout << "request `" << ch << "' not implemented\n";
            break;
        }

        cout << "? ";
        cin >> ch;
    }
}
