package com.atlassian.stash.internal.repository;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;

import javax.annotation.Nonnull;
import java.util.Arrays;

/**
 * The order in which to use to sort a Repository search.
 *
 * @since 2.6
 */
public enum RepositoryOrder {

    /**
     * Represents repository ordering by project name, then repository name and then ID (for consistency).
     *
     */
    PROJECT_NAME() {

        @Nonnull
        @Override
        public Iterable<Order> getOrder() {
            return Arrays.asList(Order.asc(PROJECT_NAME_COLUMN).ignoreCase(),
                    Order.asc(REPO_NAME_COLUMN).ignoreCase(),
                    Order.asc(REPO_ID_COLUMN));
        }
    },

    /**
     * Represents repository ordering by name and then ID (for consistency).
     * <p>
     * This ordering is independent of the project name.
     */
    REPO_NAME() {

        @Nonnull
        @Override
        public Iterable<Order> getOrder() {
            // ID is unique and the resulting sort always consistent, no column after that would make any difference
            return Arrays.asList(Order.asc(REPO_NAME_COLUMN).ignoreCase(),
                    Order.asc(REPO_ID_COLUMN));
        }
    };

    public static final RepositoryOrder DEFAULT = REPO_NAME;

    private static final String REPO_NAME_COLUMN = "name";
    private static final String REPO_ID_COLUMN = "id";
    private static final String PROJECT_NAME_COLUMN = "p.name";

    public void apply(@Nonnull Criteria criteria) {
        for (Order order : getOrder()) {
            criteria.addOrder(order);
        }
    }

    @Nonnull
    public abstract Iterable<Order> getOrder();
}
