#include <balancer/kernel/fs/threadedfile.h>
#include <balancer/kernel/thread/threadedqueue.h>

#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/coroutine/engine/impl.h>

#include <util/generic/xrange.h>
#include <util/system/tempfile.h>
#include <util/stream/file.h>
#include <util/thread/factory.h>

Y_UNIT_TEST_SUITE(TThreadedFileTest) {

    struct TData {
        TString Name;
        NSrvKernel::TThreadedQueue Queue;
        NSrvKernel::TErrorOr<NSrvKernel::TChunkPtr> Res;

        TData(TString name, TContExecutor& exec)
            : Name(name)
            , Queue(&exec, SystemThreadFactory())
        {}

        ~TData() {
            Queue.Dispose();
        }
    };

    static void DoMain(TCont*, void* arg) {
        TData& data = *(TData*)arg;
        data.Res = NSrvKernel::ThreadedFileReadAll(data.Name, &data.Queue, -1, TInstant::Max());
        data.Queue.Dispose();
    }

    Y_UNIT_TEST(TestLongFileRead) {
        TTempFileHandle tmp;

        TStringBuilder data;
        for (auto i : xrange(16127)) {
            Y_UNUSED(i);
            data << "0123456789abc";
        }
        tmp.Write(data.data(), data.size());
        TContExecutor exec(100000);
        TData dataArg(tmp.Name(), exec);
        exec.Execute(DoMain, &dataArg);
        NSrvKernel::TChunkPtr resData;
        auto err = dataArg.Res.AssignTo(resData);
        UNIT_ASSERT(!err);
        UNIT_ASSERT_VALUES_EQUAL(resData->AsStringBuf(), data);
    }
}
