// Path: src/main/java/org/blackdread/filtersortjooqapi/exception/SortingApiException.java
// public class SortingApiException extends BadUsageApiException {
// 
//     public SortingApiException(final String message) {
//         super(message);
//     }
// }


import org.blackdread.filtersortjooqapi.exception.SortingApiException;
import org.jooq.SortField;
import org.jooq.SortOrder;
import org.springframework.data.domain.Sort;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
package org.blackdread.filtersortjooqapi.sort;



/**
 * <p>Interface to  be implemented by repository that wants to provide sorting</p>
 * <p>It allows to be consistent through the app for sorting</p>
 * <p>Interface defines default methods to limit copy/paste code while still providing a way to override
 * default behavior. Using an abstract class would allow to hide internal methods but wait
 * for Java 9 private methods :)</p>
 * Created by Yoann CAPLAIN on 2017/8/25.
 */
public interface SortingJooq {

    /**
     * Empty immutable list for sorting
     *
     * @return an empty immutable sort list
     */
    @NotNull
    default Collection<SortField<?>> emptySorting() {
        return Collections.emptyList();
    }

    /**
     * TODO Change to List for return value
     *
     * @param sortSpecification Sort from Spring Data
     * @return Collection of fields to sort (can be empty if {@code sortSpecification} is null or no sort values)
     * @throws SortingApiException if any sort field given cannot be found (it should result in a 400 error message) or sort contains duplicate keys
     */
    @NotNull
    default Collection<SortField<?>> buildOrderBy(@Nullable final Sort sortSpecification) {
        Collection<SortField<?>> querySortFields = new ArrayList<>(10);

        if (sortSpecification == null) {
            return getDefaultSorting();
        }

        List<String> usedSortKey = new ArrayList<>(10);

        for (final Sort.Order specifiedField : sortSpecification) {
            String sortFieldName = specifiedField.getProperty();
            Sort.Direction sortDirection = specifiedField.getDirection();

            if (usedSortKey.contains(sortFieldName))
// Path: src/main/java/org/blackdread/filtersortjooqapi/exception/SortingApiException.java
// public class SortingApiException extends BadUsageApiException {
// 
//     public SortingApiException(final String message) {
//         super(message);
//     }
// }


// Path: src/main/java/org/blackdread/filtersortjooqapi/sort/SortingJooq.java
import org.blackdread.filtersortjooqapi.exception.SortingApiException;
import org.jooq.SortField;
import org.jooq.SortOrder;
import org.springframework.data.domain.Sort;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

package org.blackdread.filtersortjooqapi.sort;



/**
 * <p>Interface to  be implemented by repository that wants to provide sorting</p>
 * <p>It allows to be consistent through the app for sorting</p>
 * <p>Interface defines default methods to limit copy/paste code while still providing a way to override
 * default behavior. Using an abstract class would allow to hide internal methods but wait
 * for Java 9 private methods :)</p>
 * Created by Yoann CAPLAIN on 2017/8/25.
 */
public interface SortingJooq {

    /**
     * Empty immutable list for sorting
     *
     * @return an empty immutable sort list
     */
    @NotNull
    default Collection<SortField<?>> emptySorting() {
        return Collections.emptyList();
    }

    /**
     * TODO Change to List for return value
     *
     * @param sortSpecification Sort from Spring Data
     * @return Collection of fields to sort (can be empty if {@code sortSpecification} is null or no sort values)
     * @throws SortingApiException if any sort field given cannot be found (it should result in a 400 error message) or sort contains duplicate keys
     */
    @NotNull
    default Collection<SortField<?>> buildOrderBy(@Nullable final Sort sortSpecification) {
        Collection<SortField<?>> querySortFields = new ArrayList<>(10);

        if (sortSpecification == null) {
            return getDefaultSorting();
        }

        List<String> usedSortKey = new ArrayList<>(10);

        for (final Sort.Order specifiedField : sortSpecification) {
            String sortFieldName = specifiedField.getProperty();
            Sort.Direction sortDirection = specifiedField.getDirection();

            if (usedSortKey.contains(sortFieldName))
                throw new SortingApiException("Cannot sort on duplicate keys");