"""Recipe "paging": read every document, a page at a time, in object ID order.

Usage: python recipes/paging.py [page size, default 100]
"""

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from mfiles_client import run  # noqa: E402
from mfiles_values import (integer, is_not_deleted, is_object_type,  # noqa: E402
                           status_condition)
from recipe_helpers import connect, int_arg  # noqa: E402

from mfiles import IRPCSearch_pb2, IRPCSearch_pb2_grpc  # noqa: E402
from mfiles import enums_pb2 as enums  # noqa: E402
from mfiles import structs_pb2 as structs  # noqa: E402

SORT_BY_OBJECT_ID = -102  # Sort key for ascending object ID order.


def main() -> None:
    page_size = int_arg(0, 100)
    with connect() as client:
        search = client.stub(IRPCSearch_pb2_grpc.IRPCSearchStub)

        # [START paging]
        # Keyset paging: sort by object ID and ask each page for IDs above the last one seen.
        last_id, page, total = 0, 0, 0
        while True:
            response = search.SearchObjects(IRPCSearch_pb2.SearchObjectsRequest(
                conditions=[structs.SearchConditionArray(value=[
                    is_object_type(0),
                    is_not_deleted(),
                    status_condition(enums.STATUS_TYPE_OBJECT_ID,
                                     enums.CONDITION_TYPE_GREATER_THAN, integer(last_id)),
                ])],
                sorting=structs.SearchResultsSorting(rules=structs.SortRuleValueArray(
                    values=[structs.SortRule(key=SORT_BY_OBJECT_ID)])),
                limit=page_size))
            if not response.results:
                break

            page += 1
            total += len(response.results)
            first_id = response.results[0].object.object_info.obj_id.item_id.internal_id
            last_id = response.results[-1].object.object_info.obj_id.item_id.internal_id
            print(f"Page {page}: {len(response.results)} documents, IDs {first_id}-{last_id}")

            if not response.has_more_results:
                break
        # [END paging]
        print(f"Total: {total} documents in {page} pages")


if __name__ == "__main__":
    run(main)
