String TestDir;
BlockArena TestArena;

void AddCtrlPress(SDL_Keycode key) {
    Event event = {};
    event.key = key;
    event.ctrl = 1;
    event.xwindow = 1280;
    event.ywindow = 720;
    Add(&EventPlayback, event);
}

void AddText(String string) {
    Event event = {};
    event.kind = EVENT_TEXT_INPUT;
    event.xwindow = 1280;
    event.ywindow = 720;
    event.text = Copy(SysAllocator, string).data;
    Add(&EventPlayback, event);
}

void Wait(mco_coro *co) {
    Add(&EventPlayback, {EVENT_KIND_INVALID});
    for (Event *event = CoYield(co); event->kind != EVENT_KIND_INVALID; event = CoYield(co)) {
    }
}

void PlayTestOpen(mco_coro *co) {
    // Open file, move a little, then open again and verify the caret didn't move
    // String basic_env_cpp = Format(SysAllocator, "%S/test_env", TestDir);

    // AddCtrlPress(SDLK_P);
    // Add(&EventPlayback, {EVENT_KEY_PRESS, SDLK_UP, 1280, 720});
    // AddCtrlPress(SDLK_Q);

    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_PERIOD; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_PERIOD; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_F; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_S; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "s"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_R; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "r"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_C; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "c"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_ESCAPE; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_ESCAPE; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_LCTRL; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_Q; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_LCTRL; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_F; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_T; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "t"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_E; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "e"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_S; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "s"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_T; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "t"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_ESCAPE; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_ESCAPE; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_LCTRL; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_Q; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_LCTRL; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_F; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_T; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "t"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_E; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "e"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_S; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_TEXT_INPUT; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.text = "s"; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_ESCAPE; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_ESCAPE; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_LCTRL; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}
    // {Event ev = {};ev.kind = EVENT_KEY_PRESS; ev.key = SDLK_Q; ev.xwindow = 1910; ev.ywindow = 2040; ev.xmouse = 581; ev.ymouse = 952; ev.ctrl = 1; Add(&EventPlayback, ev);}

    // Wait(co);

    // {
    //     BSet main = GetActiveMainSet();
    //     Assert(main.buffer->name == basic_env_cpp);
    //     Assert(main.view->carets[0].range.min == 0);
    //     Assert(main.view->carets[0].range.max == 0);
    //     Int line = PosToLine(main.buffer, main.view->carets[0].range.min);
    //     Assert(line == 0);
    // }

    // AddCtrlPress(SDLK_DOWN);
    // AddCtrlPress(SDLK_DOWN);
    // AddCtrlPress(SDLK_DOWN);
    // Wait(co);

    // Range range = {};
    // {
    //     BSet main = GetActiveMainSet();
    //     Assert(main.view->carets[0].range.min > 0);
    //     Assert(main.view->carets[0].range.max > 0);
    //     range = main.view->carets[0].range;
    // }

    // AddCtrlPress(SDLK_P);
    // Add(&EventPlayback, {EVENT_KEY_PRESS, SDLK_UP, 1280, 720});
    // AddCtrlPress(SDLK_Q);
    // Wait(co);

    // Int buffer_len = 0;
    // {
    //     BSet main = GetActiveMainSet();
    //     Assert(main.buffer->name == basic_env_cpp);
    //     Assert(main.view->carets[0].range.min == range.min);
    //     Assert(main.view->carets[0].range.max == range.max);
    //     buffer_len = main.buffer->len;
    // }

    // AddText(Format(SysAllocator, "%S:20", basic_env_cpp));
    // AddCtrlPress(SDLK_Q);
    // Wait(co);

    // {
    //     BSet main = GetActiveMainSet();
    //     Int pos = main.view->carets[0].range.min;
    //     Int line = PosToLine(main.buffer, pos);
    //     Assert(line == 19);
    //     Assert(main.buffer->name == basic_env_cpp);
    //     Assert(main.buffer->len != buffer_len);
    //     Assert(main.buffer->dirty);
    // }

    // AddCtrlPress(SDLK_Z);
    // AddCtrlPress(SDLK_PAGEUP);
    // Wait(co);

    // {
    //     BSet main = GetActiveMainSet();
    //     Assert(main.buffer->len == buffer_len);
    //     Assert(main.view->carets[0].range.min == 0);
    //     Assert(main.view->carets[0].range.max == 0);
    // }
    ReportConsolef("%s DONE", __FUNCTION__);

}

void Test(mco_coro *co) {
    Wait(co); // First phase starts immediately but stuff is not initialized so Open acts weird
    Open(TestDir);
    PlayTestOpen(co);
    Release(&TestArena);


//    Add(&EventPlayback, {EVENT_QUIT});
}

void InitTests() {
    ConfigWaitForEvents = false;
    TestDir = Format(TestArena, "%S/test_env", GetExeDir(TestArena));
    CoData *data = CoAdd(Test);
    data->dont_wait_until_resolved = true;
}
