/*
 * Copyright 2017 Kuelap, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.mifos.individuallending.internal.service.costcomponent;

import io.mifos.individuallending.api.v1.domain.product.AccountDesignators;
import io.mifos.individuallending.api.v1.domain.product.ChargeIdentifiers;
import io.mifos.individuallending.api.v1.domain.product.LossProvisionStep;
import io.mifos.individuallending.api.v1.domain.workflow.Action;
import io.mifos.individuallending.internal.service.LossProvisionStepService;
import io.mifos.individuallending.internal.service.schedule.LossProvisionChargesService;
import io.mifos.portfolio.api.v1.domain.CostComponent;
import io.mifos.portfolio.api.v1.domain.Payment;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Matchers;
import org.mockito.Mockito;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Myrle Krantz
 */
@RunWith(Parameterized.class)
public class DisbursePaymentBuilderServiceTest {

  @Parameterized.Parameters
  public static Collection testCases() {
    final Collection<PaymentBuilderServiceTestCase> ret = new ArrayList<>();
    ret.add(simpleCase());
    return ret;
  }

  private static PaymentBuilderServiceTestCase simpleCase() {
    return new PaymentBuilderServiceTestCase("simple case");
  }

  private final PaymentBuilderServiceTestCase testCase;

  public DisbursePaymentBuilderServiceTest(final PaymentBuilderServiceTestCase testCase) {
    this.testCase = testCase;
  }

  @Test
  public void getPaymentBuilder() throws Exception {
    final LossProvisionStepService lossProvisionStepsService = Mockito.mock(LossProvisionStepService.class);
    Mockito.doReturn(Optional.of(new LossProvisionStep(0, BigDecimal.ONE))).when(lossProvisionStepsService).findByProductIdAndDaysLate(Matchers.any(), Matchers.eq(0));
    final LossProvisionChargesService lossProvisionChargesService = new LossProvisionChargesService(lossProvisionStepsService);
    final PaymentBuilder paymentBuilder = PaymentBuilderServiceTestHarness.constructCallToPaymentBuilder(
        (scheduledChargesService) -> new DisbursePaymentBuilderService(scheduledChargesService, lossProvisionChargesService), testCase);

    final Payment payment = paymentBuilder.buildPayment(Action.DISBURSE, Collections.emptySet(), testCase.forDate.toLocalDate());
    Assert.assertNotNull(payment);
    final Map<String, CostComponent> mappedCostComponents = payment.getCostComponents().stream()
        .collect(Collectors.toMap(CostComponent::getChargeIdentifier, x -> x));

    Assert.assertEquals(
        testCase.paymentSize,
        mappedCostComponents.get(ChargeIdentifiers.DISBURSE_PAYMENT_ID).getAmount());
    Assert.assertEquals(
        testCase.paymentSize.multiply(BigDecimal.valueOf(1, 2)).setScale(2, BigDecimal.ROUND_HALF_EVEN),
        paymentBuilder.getBalanceAdjustments().get(AccountDesignators.PRODUCT_LOSS_ALLOWANCE));
    Assert.assertEquals(
        testCase.paymentSize.multiply(BigDecimal.valueOf(1, 2)).negate().setScale(2, BigDecimal.ROUND_HALF_EVEN),
        paymentBuilder.getBalanceAdjustments().get(AccountDesignators.GENERAL_LOSS_ALLOWANCE));
  }

}