


package net.northking.cctp.common.db;


import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import net.northking.cctp.common.http.QueryByPage;
import org.springframework.beans.BeanUtils;

import java.util.List;

/**
 * 数据持久层分页服务
 *
 * @param <T> 实例对象
 */
public abstract class PaginationService<T> extends AbstractService<T>
{
  private static final int MAX_PAGE_SIZE = 500;

  @Override
  public List<T> findAll(OrderBy orderBy)
  {
    return query(createEntity(), orderBy);
  }

  @Override
  public List<T> query(T record, OrderBy orderBy)
  {
    return query(record, orderBy, 0, 0).getRecords();
  }

  public Pagination<T> findAll(int pageNo, int pageSize)
  {
    return query(createEntity(), null, pageNo, pageSize);
  }

  public Pagination<T> findAll(OrderBy orderBy, int pageNo, int pageSize)
  {
    return query(createEntity(), orderBy, pageNo, pageSize);
  }

  public Pagination<T> query(T record, int pageNo, int pageSize)
  {
    return query(record, null, pageNo, pageSize);
  }

  protected <E> Pagination<E> query(T record, OrderBy orderBy, int pageNo, int pageSize, PagingQueryDao pagingQueryDao)
  {
    if (pageNo <= 0)
    {
      pageNo = 1;
    }
    if (pageSize <= 0 || pageSize > MAX_PAGE_SIZE)
    {
      pageSize = MAX_PAGE_SIZE;
    }

    DefaultPagination<E> pagination = new DefaultPagination<>();
    pagination.setPageSize(pageSize);
    pagination.setPageNo(pageNo);

    OrderBy sort = orderBy;
    if (sort == null || sort.isEmpty())
    {
      sort = defaultOrderBy();
    }

    if (sort != null && sort.isNotEmpty())
    {
      PageMethod.orderBy(sort.toString());
    }

    Page<E> page = PageMethod.startPage(pageNo, pageSize);

    beforeQuery(record);
    List<E> result;
    if (pagingQueryDao == null)
    {
      result = getDao().query(record);
    } else
    {
      result = pagingQueryDao.pagingQuery(record);
    }
    pagination.setRecords(result);
    pagination.setRecordCount(page.getTotal());
    return pagination;
  }

  protected OrderBy defaultOrderBy()
  {
    return null;
  }

  @Override
  public Pagination<T> query(T record, OrderBy orderBy, int pageNo, int pageSize)
  {
    return query(record, orderBy, pageNo, pageSize, null);
  }

  @Override
  public <E> Pagination<E> pagingQuery(QueryByPage<?> queryByPage)
  {
    return pagingQuery(queryByPage, getDao());
  }

  @Override
  public long count(T record)
  {
    beforeQuery(record);
    return getDao().queryCount(record);
  }

  public <E> Pagination<E> pagingQuery(QueryByPage<?> queryByPage, PagingQueryDao pagingQueryDao)
  {
    int pageNo = queryByPage.getPageNo();
    int pageSize = queryByPage.getPageSize();
    OrderBy orderBy = queryByPage.toSqlOrderBy();
    Object queryData = queryByPage.getQuery();
    T example = createEntity();
    if (queryData != null)
    {
      BeanUtils.copyProperties(queryData, example);
    }
    return query(example, orderBy, pageNo, pageSize, pagingQueryDao);
  }

  protected void beforeQuery(T example)
  {

  }


}
