using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace MCPForUnity.Editor.Helpers
{
///
/// Standard pagination request for all paginated tool operations.
/// Provides consistent handling of page_size/pageSize and cursor/page_number parameters.
///
public class PaginationRequest
{
///
/// Number of items per page. Default is 50.
///
public int PageSize { get; set; } = 50;
///
/// 0-based cursor position for the current page.
///
public int Cursor { get; set; } = 0;
///
/// Creates a PaginationRequest from JObject parameters.
/// Accepts both snake_case and camelCase parameter names for flexibility.
/// Converts 1-based page_number to 0-based cursor if needed.
///
public static PaginationRequest FromParams(JObject @params, int defaultPageSize = 50)
{
if (@params == null)
return new PaginationRequest { PageSize = defaultPageSize };
// Accept both page_size and pageSize
int pageSize = ParamCoercion.CoerceInt(
@params["page_size"] ?? @params["pageSize"],
defaultPageSize
);
// Accept both cursor (0-based) and page_number (convert 1-based to 0-based)
var cursorToken = @params["cursor"];
var pageNumberToken = @params["page_number"] ?? @params["pageNumber"];
int cursor;
if (cursorToken != null)
{
cursor = ParamCoercion.CoerceInt(cursorToken, 0);
}
else if (pageNumberToken != null)
{
// Convert 1-based page_number to 0-based cursor
int pageNumber = ParamCoercion.CoerceInt(pageNumberToken, 1);
cursor = (pageNumber - 1) * pageSize;
if (cursor < 0) cursor = 0;
}
else
{
cursor = 0;
}
return new PaginationRequest
{
PageSize = pageSize > 0 ? pageSize : defaultPageSize,
Cursor = cursor
};
}
}
///
/// Standard pagination response for all paginated tool operations.
/// Provides consistent response structure across all tools.
///
/// The type of items in the paginated list
public class PaginationResponse
{
///
/// The items on the current page.
///
[JsonProperty("items")]
public List Items { get; set; } = new List();
///
/// The cursor position for the current page (0-based).
///
[JsonProperty("cursor")]
public int Cursor { get; set; }
///
/// The cursor for the next page, or null if this is the last page.
///
[JsonProperty("nextCursor")]
public int? NextCursor { get; set; }
///
/// Total number of items across all pages.
///
[JsonProperty("totalCount")]
public int TotalCount { get; set; }
///
/// Number of items per page.
///
[JsonProperty("pageSize")]
public int PageSize { get; set; }
///
/// Whether there are more items after this page.
///
[JsonProperty("hasMore")]
public bool HasMore => NextCursor.HasValue;
///
/// Creates a PaginationResponse from a full list of items and pagination parameters.
///
/// The full list of items to paginate
/// The pagination request parameters
/// A paginated response with the appropriate slice of items
public static PaginationResponse Create(IList allItems, PaginationRequest request)
{
int totalCount = allItems.Count;
int cursor = request.Cursor;
int pageSize = request.PageSize;
// Clamp cursor to valid range
if (cursor < 0) cursor = 0;
if (cursor > totalCount) cursor = totalCount;
// Get the page of items
var items = new List();
int endIndex = System.Math.Min(cursor + pageSize, totalCount);
for (int i = cursor; i < endIndex; i++)
{
items.Add(allItems[i]);
}
// Calculate next cursor
int? nextCursor = endIndex < totalCount ? endIndex : (int?)null;
return new PaginationResponse
{
Items = items,
Cursor = cursor,
NextCursor = nextCursor,
TotalCount = totalCount,
PageSize = pageSize
};
}
}
}