content: package io.aiven.klaw.helpers;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.function.BiFunction;
  import org.apache.commons.lang3.math.NumberUtils;
  
  public class Pager {
    public static final int DEFAULT_REC_PER_PAGE = 20;
  
    private static int deriveCurrentPage(String pageNo, String currentPage, int totalPages) {
      return switch (pageNo) {
        case ">" -> Integer.parseInt(currentPage) + 1;
        case ">>" -> totalPages;
        case "<" -> Integer.parseInt(currentPage) - 1;
        case "<<" -> 1;
        default -> !NumberUtils.isCreatable(pageNo)
            ? defaultToCurrentPage(currentPage)
            : Integer.parseInt(pageNo);
      };
    }
  
    private static int defaultToCurrentPage(String currentPage) {
      return !NumberUtils.isCreatable(currentPage) ? 1 : Integer.parseInt(currentPage);
    }
  
    private static void getAllPagesList(
        int pageNo, String currentPage, int totalPages, List<String> numList) {
  
      if (currentPage != null && pageNo > 1 && totalPages > 1 && !currentPage.isEmpty()) {
        numList.add("<<");
        numList.add("<");
      }
  
      if (totalPages > pageNo) {
        numList.add(Integer.toString(pageNo));
        numList.add(">");
        numList.add(">>");
      } else if (totalPages == pageNo) {
        numList.add(Integer.toString(pageNo));
      }
    }
  
    public static <INPUT, OUTPUT> List<OUTPUT> getItemsList(
        String pageNo,
        String currentPage,
        List<INPUT> aclListMap,
        BiFunction<PageContext, INPUT, OUTPUT> consumer) {
      return getItemsList(pageNo, currentPage, DEFAULT_REC_PER_PAGE, aclListMap, consumer);
    }
  
    public static <INPUT, OUTPUT> List<OUTPUT> getItemsList(
        String pageNo,
        String currentPage,
        int recsPerPage,
        List<INPUT> aclListMap,
        BiFunction<PageContext, INPUT, OUTPUT> consumer) {
      List<OUTPUT> aclListMapUpdated = new ArrayList<>();
  
      int totalRecs = aclListMap.size();
      int totalPages =
          aclListMap.size() / recsPerPage + (aclListMap.size() % recsPerPage > 0 ? 1 : 0);
  
      final int requestPageNo = deriveCurrentPage(pageNo, currentPage, totalPages);
      final int startVar = Math.max(0, (requestPageNo - 1) * recsPerPage);
      final int lastVar = Math.min(requestPageNo * recsPerPage, totalRecs);
  
      List<String> numList = new ArrayList<>();
      getAllPagesList(requestPageNo, currentPage, totalPages, numList);
  
      PageContext pageContext =
          PageContext.of(totalPages, numList, Integer.toString(requestPageNo), totalRecs);
      for (int i = startVar; i < lastVar; i++) {
        aclListMapUpdated.add(consumer.apply(pageContext, aclListMap.get(i)));
      }
      return aclListMapUpdated;
    }
  
    public static class PageContext {
      private final String totalPages;
      private final List<String> allPageNos;
      private final String pageNo;
      private final int totalRecs;
  
      private PageContext(int totalPages, List<String> allPageNos, String pageNo, int totalRecs) {
        this.totalPages = totalPages + "";
        this.allPageNos = allPageNos;
        this.pageNo = pageNo;
        this.totalRecs = totalRecs;
      }
  
      public static PageContext of(
          int totalPages, List<String> allPageNos, String pageNo, int totalRecs) {
        return new PageContext(totalPages, allPageNos, pageNo, totalRecs);
      }
  
      public String getTotalPages() {
        return totalPages;
      }
  
      public List<String> getAllPageNos() {
        return allPageNos;
      }
  
      public String getPageNo() {
        return pageNo;
      }
  
      public int getTotalRecs() {
        return totalRecs;
      }
    }
  }
  