package io.teiler.server.services;

import io.teiler.server.dto.Compensation;
import io.teiler.server.dto.Debt;
import io.teiler.server.services.util.GroupUtil;
import io.teiler.server.services.util.settleup.PersonChooser;
import io.teiler.server.services.util.settleup.TopBottomChooser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * Provides service-methods for suggested compensations.
 *
 * @author dthoma
 */
@Service
public class SuggestedCompensationService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SuggestedCompensationService.class);

    @Autowired
    private GroupUtil groupUtil;

    @Autowired
    private DebtService debtService;

    /**
     * Gets the suggested compensations for this group.
     *
     * @param groupId The group to get the suggested compensations for.
     * @return The suggested compensations for this group
     */
    public List<Compensation> getSuggestedCompensations(String groupId) {
        groupUtil.checkIdExists(groupId);

        List<Compensation> suggestedCompensations = new LinkedList<>();
        PersonChooser personChooser = new TopBottomChooser(debtService.getDebts(groupId));

        while (personChooser.personsLeft()) {
            Debt creditor = personChooser.getNextCreditor();
            Debt debitor = personChooser.getNextDebitor();

            int newCreditorBalance;
            int newDebitorBalance;
            int balance;

            if (creditor.getBalance() >= -debitor.getBalance()) {
                balance = -debitor.getBalance();

                newCreditorBalance = creditor.getBalance() + debitor.getBalance();
                newDebitorBalance = 0;
            } else {
                balance = creditor.getBalance();

                newCreditorBalance = 0;
                newDebitorBalance = debitor.getBalance() + creditor.getBalance();
            }

            Compensation compensation = new Compensation(
                null,
                balance,
                debitor.getPerson(),
                creditor.getPerson()
            );
            suggestedCompensations.add(compensation);

            personChooser.updateDebt(newCreditorBalance, creditor);
            personChooser.updateDebt(newDebitorBalance, debitor);
        }

        LOGGER.debug("View suggested compensations: {}", suggestedCompensations);
        return suggestedCompensations;
    }
}

@@ -1604,267 +1604,875 @@
 ce;%0A
-%0A            if (creditor.getBalance() %3E= -debitor.getBalance()) %7B%0A                balance = -debitor.getBalance();%0A%0A                newCreditorBalance = creditor.getBalance() + debitor.getBalance();%0A                newDebitorBalance = 0;%0A            %7D else %7B
+            %0A            // The idea is to eliminate (balance = 0) a creditor or a debitor each loop%0A            if (creditor.getBalance() %3E= -debitor.getBalance()) %7B%0A                /*%0A                The creditor's credit is higher than (or equal to) the debitor's debt%0A                Therefore, we can eliminate the debitor%0A                The debitor will pay his whole debt to the creditor%0A                */%0A                balance = -debitor.getBalance();%0A%0A                newCreditorBalance = creditor.getBalance() + debitor.getBalance();%0A                newDebitorBalance = 0;%0A            %7D else %7B%0A                /*%0A                The debitor's debt is higher than the creditor's credit%0A                Therefore, we can eliminate the creditor%0A                The debitor will pay the remaining balance of the creditor and ease his debt%0A                */
 %0A   

Add comments to explain the algorithm