/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 org.apache.fineract.portfolio.deliquency;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyIterable;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.domain.ActionContext;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAccountDelinquencyPauseChangedBusinessEvent;
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketMappingsRepository;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketRepository;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyRange;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyRangeRepository;
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyAction;
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyActionRepository;
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyTagHistory;
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyTagHistoryRepository;
import org.apache.fineract.portfolio.delinquency.domain.LoanInstallmentDelinquencyTag;
import org.apache.fineract.portfolio.delinquency.domain.LoanInstallmentDelinquencyTagRepository;
import org.apache.fineract.portfolio.delinquency.helper.DelinquencyEffectivePauseHelper;
import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService;
import org.apache.fineract.portfolio.delinquency.service.DelinquencyWritePlatformServiceImpl;
import org.apache.fineract.portfolio.delinquency.service.LoanDelinquencyDomainService;
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyActionParseAndValidator;
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyBucketParseAndValidator;
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyRangeParseAndValidator;
import org.apache.fineract.portfolio.delinquency.validator.LoanDelinquencyActionData;
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
import org.apache.fineract.portfolio.loanaccount.data.LoanDelinquencyData;
import org.apache.fineract.portfolio.loanaccount.data.LoanScheduleDelinquencyData;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class DelinquencyWritePlatformServiceRangeChangeEventTest {

    @Mock
    private DelinquencyBucketParseAndValidator dataValidatorBucket;
    @Mock
    private DelinquencyRangeParseAndValidator dataValidatorRange;
    @Mock
    private DelinquencyRangeRepository repositoryRange;
    @Mock
    private DelinquencyBucketRepository repositoryBucket;
    @Mock
    private DelinquencyBucketMappingsRepository repositoryBucketMappings;
    @Mock
    private LoanDelinquencyTagHistoryRepository loanDelinquencyTagRepository;
    @Mock
    private LoanRepositoryWrapper loanRepository;
    @Mock
    private LoanProductRepository loanProductRepository;
    @Mock
    private BusinessEventNotifierService businessEventNotifierService;
    @Mock
    private LoanDelinquencyDomainService loanDelinquencyDomainService;
    @Mock
    private LoanInstallmentDelinquencyTagRepository loanInstallmentDelinquencyTagRepository;
    @Mock
    private DelinquencyReadPlatformService delinquencyReadPlatformService;
    @Mock
    private DelinquencyActionParseAndValidator delinquencyActionParseAndValidator;
    @Mock
    private LoanDelinquencyActionRepository loanDelinquencyActionRepository;
    @Mock
    private DelinquencyEffectivePauseHelper delinquencyEffectivePauseHelper;

    @InjectMocks
    private DelinquencyWritePlatformServiceImpl underTest;

    @BeforeEach
    public void setUp() {
        ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
        ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
        ThreadLocalContextUtil
                .setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, LocalDate.now(ZoneId.systemDefault()))));
    }

    @Test
    public void givenLoanAccountWithDelinquencyBucketWhenRangeChangeThenEventIsRaised() {
        ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDeliquencyRangeChangeEvent = ArgumentCaptor
                .forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
        // given
        final List<LoanDelinquencyActionData> effectiveDelinquencyList = Collections.emptyList();
        Loan loanForProcessing = Mockito.mock(Loan.class);
        LoanProduct loanProduct = Mockito.mock(LoanProduct.class);
        DelinquencyRange range1 = DelinquencyRange.instance("Range1", 1, 2);
        range1.setId(1L);
        DelinquencyRange range2 = DelinquencyRange.instance("Range30", 3, 30);
        range2.setId(2L);
        List<DelinquencyRange> listDelinquencyRanges = Arrays.asList(range1, range2);
        DelinquencyBucket delinquencyBucket = new DelinquencyBucket("test Bucket");
        delinquencyBucket.setRanges(listDelinquencyRanges);

        LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(2);
        LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
                loanForProcessing);
        CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
                null, null, null, null);

        Map<Long, CollectionData> installmentsCollection = new HashMap<>();

        LoanDelinquencyData loanDelinquencyData = new LoanDelinquencyData(collectionData, installmentsCollection);

        when(loanForProcessing.getLoanProduct()).thenReturn(loanProduct);
        when(loanProduct.getDelinquencyBucket()).thenReturn(delinquencyBucket);
        when(loanForProcessing.hasDelinquencyBucket()).thenReturn(true);
        when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(false);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
        when(loanDelinquencyDomainService.getLoanDelinquencyData(loanForProcessing, effectiveDelinquencyList))
                .thenReturn(loanDelinquencyData);

        // when
        underTest.applyDelinquencyTagToLoan(loanScheduleDelinquencyData, effectiveDelinquencyList);

        // then
        verify(loanDelinquencyTagRepository, times(1)).saveAllAndFlush(anyIterable());
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDeliquencyRangeChangeEvent.capture());
        Loan loanPayloadForEvent = loanDeliquencyRangeChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);
    }

    @Test
    public void givenLoanAccountWithDelinquencyBucketWhenNoRangeChangeThenNoEventIsRaised() {
        // given
        final List<LoanDelinquencyActionData> effectiveDelinquencyList = Collections.emptyList();
        Loan loanForProcessing = Mockito.mock(Loan.class);
        LoanProduct loanProduct = Mockito.mock(LoanProduct.class);

        DelinquencyRange range1 = DelinquencyRange.instance("Range1", 1, 2);
        range1.setId(1L);
        DelinquencyRange range2 = DelinquencyRange.instance("Range30", 3, 30);
        range2.setId(2L);
        List<DelinquencyRange> listDelinquencyRanges = Arrays.asList(range1, range2);

        DelinquencyBucket delinquencyBucket = new DelinquencyBucket("test Bucket");
        delinquencyBucket.setRanges(listDelinquencyRanges);

        LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate();
        LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 2L,
                loanForProcessing);

        CollectionData collectionData = CollectionData.template();

        Map<Long, CollectionData> installmentsCollection = new HashMap<>();

        LoanDelinquencyData loanDelinquencyData = new LoanDelinquencyData(collectionData, installmentsCollection);

        when(loanForProcessing.getLoanProduct()).thenReturn(loanProduct);
        when(loanProduct.getDelinquencyBucket()).thenReturn(delinquencyBucket);
        when(loanForProcessing.hasDelinquencyBucket()).thenReturn(true);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
        when(loanDelinquencyDomainService.getLoanDelinquencyData(loanForProcessing, effectiveDelinquencyList))
                .thenReturn(loanDelinquencyData);

        // when
        underTest.applyDelinquencyTagToLoan(loanScheduleDelinquencyData, effectiveDelinquencyList);

        // then
        verify(loanDelinquencyTagRepository, times(0)).saveAllAndFlush(anyIterable());
        verify(businessEventNotifierService, times(0)).notifyPostBusinessEvent(any());
    }

    @Test
    public void givenLoanAccountWithNoDelinquencyBucketThenNoEventIsRaised() {
        // given
        final List<LoanDelinquencyActionData> effectiveDelinquencyList = Collections.emptyList();
        Loan loanForProcessing = Mockito.mock(Loan.class);

        LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate();
        LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 2L,
                loanForProcessing);

        when(loanForProcessing.hasDelinquencyBucket()).thenReturn(false);

        // when
        underTest.applyDelinquencyTagToLoan(loanScheduleDelinquencyData, effectiveDelinquencyList);

        // then
        verify(loanDelinquencyTagRepository, times(0)).saveAllAndFlush(anyIterable());
        verify(businessEventNotifierService, times(0)).notifyPostBusinessEvent(any());

    }

    @Test
    public void givenLoanAccountWithOverdueInstallmentAndEnableInstallmentThenDelinquencyRangeIsSetForInstallmentTest() {
        ArgumentCaptor<List<LoanInstallmentDelinquencyTag>> loanInstallmentDelinquencyTagsArgumentCaptor = ArgumentCaptor
                .forClass(List.class);
        ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDelinquencyRangeChangeEvent = ArgumentCaptor
                .forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
        // given
        final List<LoanDelinquencyActionData> effectiveDelinquencyList = Collections.emptyList();
        Loan loanForProcessing = Mockito.mock(Loan.class);
        LoanProduct loanProduct = Mockito.mock(LoanProduct.class);
        DelinquencyRange range1 = DelinquencyRange.instance("Range1", 1, 2);
        range1.setId(1L);
        DelinquencyRange range2 = DelinquencyRange.instance("Range30", 3, 30);
        range2.setId(2L);
        List<DelinquencyRange> listDelinquencyRanges = Arrays.asList(range1, range2);
        DelinquencyBucket delinquencyBucket = new DelinquencyBucket("test Bucket");
        delinquencyBucket.setRanges(listDelinquencyRanges);

        final Long daysDiff = 2L;
        final LocalDate fromDate = DateUtils.getBusinessLocalDate().minusMonths(1).minusDays(daysDiff);
        final LocalDate dueDate = DateUtils.getBusinessLocalDate().minusDays(daysDiff);
        final BigDecimal installmentPrincipalAmount = BigDecimal.valueOf(100);
        final BigDecimal zeroAmount = BigDecimal.ZERO;

        LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(loanForProcessing, 1, fromDate, dueDate,
                installmentPrincipalAmount, zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), zeroAmount);
        installment.setId(1L);

        List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installment);

        LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(2);
        LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
                loanForProcessing);
        CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
                null, null, null, null);

        CollectionData installmentCollectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate,
                installmentPrincipalAmount, null, null, null, null, null, null);

        Map<Long, CollectionData> installmentsCollection = new HashMap<>();
        installmentsCollection.put(1L, installmentCollectionData);

        LoanDelinquencyData loanDelinquencyData = new LoanDelinquencyData(collectionData, installmentsCollection);

        when(loanForProcessing.getLoanProduct()).thenReturn(loanProduct);
        when(loanProduct.getDelinquencyBucket()).thenReturn(delinquencyBucket);
        when(loanForProcessing.hasDelinquencyBucket()).thenReturn(true);
        when(loanForProcessing.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
        when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(true);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
        when(loanDelinquencyDomainService.getLoanDelinquencyData(loanForProcessing, effectiveDelinquencyList))
                .thenReturn(loanDelinquencyData);
        when(loanInstallmentDelinquencyTagRepository.findByLoanAndInstallment(loanForProcessing, repaymentScheduleInstallments.get(0)))
                .thenReturn(Optional.empty());

        // when
        underTest.applyDelinquencyTagToLoan(loanScheduleDelinquencyData, effectiveDelinquencyList);

        // then
        verify(loanDelinquencyTagRepository, times(1)).saveAllAndFlush(anyIterable());
        verify(loanInstallmentDelinquencyTagRepository, times(1)).saveAllAndFlush(loanInstallmentDelinquencyTagsArgumentCaptor.capture());

        List<LoanInstallmentDelinquencyTag> installmentDelinquencyTags = loanInstallmentDelinquencyTagsArgumentCaptor.getValue();
        assertEquals(1, installmentDelinquencyTags.size());
        assertEquals(1, installmentDelinquencyTags.get(0).getInstallment().getInstallmentNumber());
        assertEquals(1, installmentDelinquencyTags.get(0).getDelinquencyRange().getId());
        assertEquals(installmentPrincipalAmount, installmentDelinquencyTags.get(0).getOutstandingAmount());

        // verify range change event is raised
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyRangeChangeEvent.capture());
        Loan loanPayloadForEvent = loanDelinquencyRangeChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);
    }

    @Test
    public void givenLoanAccountWithOverdueInstallmentAndEnableInstallmentThenDelinquencyRangeChangesForInstallmentTest() {
        ArgumentCaptor<List<LoanInstallmentDelinquencyTag>> loanInstallmentDelinquencyTagsArgumentCaptor = ArgumentCaptor
                .forClass(List.class);
        ArgumentCaptor<LoanInstallmentDelinquencyTag> loanInstallmentDelinquencyTagArgumentCaptorForDelete = ArgumentCaptor
                .forClass(LoanInstallmentDelinquencyTag.class);

        ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDelinquencyRangeChangeEvent = ArgumentCaptor
                .forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
        // given
        final List<LoanDelinquencyActionData> effectiveDelinquencyList = Collections.emptyList();
        Loan loanForProcessing = Mockito.mock(Loan.class);
        LoanProduct loanProduct = Mockito.mock(LoanProduct.class);
        DelinquencyRange range1 = DelinquencyRange.instance("Range1", 1, 2);
        range1.setId(1L);
        DelinquencyRange range2 = DelinquencyRange.instance("Range30", 3, 30);
        range2.setId(2L);
        List<DelinquencyRange> listDelinquencyRanges = Arrays.asList(range1, range2);
        DelinquencyBucket delinquencyBucket = new DelinquencyBucket("test Bucket");
        delinquencyBucket.setRanges(listDelinquencyRanges);

        final Long daysDiff = 2L;
        final LocalDate fromDate = DateUtils.getBusinessLocalDate().minusMonths(1).minusDays(daysDiff);
        final LocalDate dueDate = DateUtils.getBusinessLocalDate().minusDays(daysDiff);
        final BigDecimal installmentPrincipalAmount = BigDecimal.valueOf(100);
        final BigDecimal zeroAmount = BigDecimal.ZERO;

        LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(loanForProcessing, 1, fromDate, dueDate,
                installmentPrincipalAmount, zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), zeroAmount);
        installment.setId(1L);

        List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installment);

        LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(29);
        LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
                loanForProcessing);
        CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate, BigDecimal.ZERO, null, null,
                null, null, null, null);

        CollectionData installmentCollectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate,
                installmentPrincipalAmount, null, null, null, null, null, null);

        Map<Long, CollectionData> installmentsCollection = new HashMap<>();
        installmentsCollection.put(1L, installmentCollectionData);

        LoanDelinquencyData loanDelinquencyData = new LoanDelinquencyData(collectionData, installmentsCollection);

        LoanInstallmentDelinquencyTag previousInstallmentTag = new LoanInstallmentDelinquencyTag();
        previousInstallmentTag.setDelinquencyRange(range1);

        when(loanForProcessing.getLoanProduct()).thenReturn(loanProduct);
        when(loanProduct.getDelinquencyBucket()).thenReturn(delinquencyBucket);
        when(loanForProcessing.hasDelinquencyBucket()).thenReturn(true);
        when(loanForProcessing.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
        when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(true);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
        when(loanDelinquencyDomainService.getLoanDelinquencyData(loanForProcessing, effectiveDelinquencyList))
                .thenReturn(loanDelinquencyData);
        when(loanInstallmentDelinquencyTagRepository.findByLoanAndInstallment(loanForProcessing, repaymentScheduleInstallments.get(0)))
                .thenReturn(Optional.of(previousInstallmentTag));

        // when
        underTest.applyDelinquencyTagToLoan(loanScheduleDelinquencyData, effectiveDelinquencyList);

        // then
        verify(loanDelinquencyTagRepository, times(1)).saveAllAndFlush(anyIterable());
        verify(loanInstallmentDelinquencyTagRepository, times(1)).saveAllAndFlush(loanInstallmentDelinquencyTagsArgumentCaptor.capture());
        verify(loanInstallmentDelinquencyTagRepository, times(1)).delete(loanInstallmentDelinquencyTagArgumentCaptorForDelete.capture());

        List<LoanInstallmentDelinquencyTag> installmentDelinquencyTags = loanInstallmentDelinquencyTagsArgumentCaptor.getValue();
        assertEquals(1, installmentDelinquencyTags.size());
        assertEquals(1, installmentDelinquencyTags.get(0).getInstallment().getInstallmentNumber());
        assertEquals(2, installmentDelinquencyTags.get(0).getDelinquencyRange().getId());
        assertEquals(installmentPrincipalAmount, installmentDelinquencyTags.get(0).getOutstandingAmount());

        LoanInstallmentDelinquencyTag deletedInstallmentDelinquencyTag = loanInstallmentDelinquencyTagArgumentCaptorForDelete.getValue();
        assertNotNull(deletedInstallmentDelinquencyTag);
        assertEquals(previousInstallmentTag, deletedInstallmentDelinquencyTag);

        // verify range change event is raised
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyRangeChangeEvent.capture());
        Loan loanPayloadForEvent = loanDelinquencyRangeChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);

    }

    @Test
    public void givenLoanAccountWithOverdueInstallmentsAndEnableInstallmentThenDelinquencyRangeChangesEventWhenOneOfInstallmentIsOutOfDelinquencyTest() {
        ArgumentCaptor<LoanInstallmentDelinquencyTag> loanInstallmentDelinquencyTagArgumentCaptorForDelete = ArgumentCaptor
                .forClass(LoanInstallmentDelinquencyTag.class);

        ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDelinquencyRangeChangeEvent = ArgumentCaptor
                .forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
        final List<LoanDelinquencyActionData> effectiveDelinquencyList = Collections.emptyList();
        // given
        Loan loanForProcessing = Mockito.mock(Loan.class);
        LoanProduct loanProduct = Mockito.mock(LoanProduct.class);
        DelinquencyRange range1 = DelinquencyRange.instance("Range1", 1, 2);
        range1.setId(1L);
        DelinquencyRange range2 = DelinquencyRange.instance("Range30", 3, 30);
        range2.setId(2L);
        List<DelinquencyRange> listDelinquencyRanges = Arrays.asList(range1, range2);
        DelinquencyBucket delinquencyBucket = new DelinquencyBucket("test Bucket");
        delinquencyBucket.setRanges(listDelinquencyRanges);

        final Long daysDiff = 2L;
        final LocalDate fromDate = DateUtils.getBusinessLocalDate().minusMonths(1).minusDays(daysDiff);
        final LocalDate dueDate = DateUtils.getBusinessLocalDate().minusDays(daysDiff);
        final BigDecimal installmentPrincipalAmount = BigDecimal.valueOf(100);
        final BigDecimal zeroAmount = BigDecimal.ZERO;

        LoanRepaymentScheduleInstallment installment_1 = new LoanRepaymentScheduleInstallment(loanForProcessing, 1, fromDate, dueDate,
                installmentPrincipalAmount, zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), zeroAmount);
        installment_1.setId(1L);

        LoanRepaymentScheduleInstallment installment_2 = new LoanRepaymentScheduleInstallment(loanForProcessing, 2, fromDate, dueDate,
                installmentPrincipalAmount, zeroAmount, zeroAmount, zeroAmount, false, new HashSet<>(), zeroAmount);
        installment_2.setId(2L);

        List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = Arrays.asList(installment_1, installment_2);

        LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(29);
        LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
                loanForProcessing);
        CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate, BigDecimal.ZERO, null, null,
                null, null, null, null);

        CollectionData installmentCollectionData_1 = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate,
                installmentPrincipalAmount, null, null, null, null, null, null);

        CollectionData installmentCollectionData_2 = new CollectionData(BigDecimal.ZERO, 0L, null, 0L, null, installmentPrincipalAmount,
                null, null, null, null, null, null);

        Map<Long, CollectionData> installmentsCollection = new HashMap<>();
        installmentsCollection.put(1L, installmentCollectionData_1);
        installmentsCollection.put(2L, installmentCollectionData_2);

        LoanDelinquencyData loanDelinquencyData = new LoanDelinquencyData(collectionData, installmentsCollection);

        LoanInstallmentDelinquencyTag previousInstallmentTag_1 = new LoanInstallmentDelinquencyTag();
        previousInstallmentTag_1.setDelinquencyRange(range2);

        LoanInstallmentDelinquencyTag previousInstallmentTag = new LoanInstallmentDelinquencyTag();
        previousInstallmentTag.setDelinquencyRange(range1);

        when(loanForProcessing.getLoanProduct()).thenReturn(loanProduct);
        when(loanProduct.getDelinquencyBucket()).thenReturn(delinquencyBucket);
        when(loanForProcessing.hasDelinquencyBucket()).thenReturn(true);
        when(loanForProcessing.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
        when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(true);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
        when(loanDelinquencyDomainService.getLoanDelinquencyData(loanForProcessing, effectiveDelinquencyList))
                .thenReturn(loanDelinquencyData);
        when(loanInstallmentDelinquencyTagRepository.findByLoanAndInstallment(loanForProcessing, repaymentScheduleInstallments.get(0)))
                .thenReturn(Optional.of(previousInstallmentTag_1));
        when(loanInstallmentDelinquencyTagRepository.findByLoanAndInstallment(loanForProcessing, repaymentScheduleInstallments.get(1)))
                .thenReturn(Optional.of(previousInstallmentTag));

        // when
        underTest.applyDelinquencyTagToLoan(loanScheduleDelinquencyData, effectiveDelinquencyList);

        // then
        verify(loanDelinquencyTagRepository, times(1)).saveAllAndFlush(anyIterable());
        verify(loanInstallmentDelinquencyTagRepository, times(1)).delete(loanInstallmentDelinquencyTagArgumentCaptorForDelete.capture());

        LoanInstallmentDelinquencyTag deletedInstallmentDelinquencyTag = loanInstallmentDelinquencyTagArgumentCaptorForDelete.getValue();
        assertNotNull(deletedInstallmentDelinquencyTag);
        assertEquals(previousInstallmentTag, deletedInstallmentDelinquencyTag);

        // verify range change event is raised
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyRangeChangeEvent.capture());
        Loan loanPayloadForEvent = loanDelinquencyRangeChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);

    }

    @Test
    public void givenLoanAccountEnableInstallmentLevelDelinquencyWhenLoanIsOutOfDelinquencyEventIsRaisedTest() {
        ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDelinquencyRangeChangeEvent = ArgumentCaptor
                .forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
        // given
        Loan loanForProcessing = Mockito.mock(Loan.class);
        DelinquencyRange range1 = DelinquencyRange.instance("Range1", 1, 2);
        range1.setId(1L);
        DelinquencyRange range2 = DelinquencyRange.instance("Range30", 3, 30);
        range2.setId(2L);
        List<DelinquencyRange> listDelinquencyRanges = Arrays.asList(range1, range2);
        DelinquencyBucket delinquencyBucket = new DelinquencyBucket("test Bucket");
        delinquencyBucket.setRanges(listDelinquencyRanges);

        LoanDelinquencyTagHistory prevTagForLoan = new LoanDelinquencyTagHistory();
        prevTagForLoan.setDelinquencyRange(range1);

        when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(true);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.of(prevTagForLoan));

        // when
        underTest.removeDelinquencyTagToLoan(loanForProcessing);

        verify(loanInstallmentDelinquencyTagRepository, times(1)).deleteAllLoanInstallmentsTags(anyLong());
        // verify range change event is raised
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyRangeChangeEvent.capture());
        Loan loanPayloadForEvent = loanDelinquencyRangeChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);

    }

    @Test
    public void givenLoanAccountWhenBackdatedPauseActionThenLoanDelinquencyPauseChangeBusinessEventIsRaisedTest() {
        ArgumentCaptor<LoanAccountDelinquencyPauseChangedBusinessEvent> loanDelinquencyPauseChangeEvent = ArgumentCaptor
                .forClass(LoanAccountDelinquencyPauseChangedBusinessEvent.class);
        // given
        Loan loanForProcessing = Mockito.mock(Loan.class);
        loanForProcessing.setId(1L);

        JsonCommand command = Mockito.mock(JsonCommand.class);

        // Pause period
        LocalDate startDate = DateUtils.getBusinessLocalDate().minusDays(8);
        LocalDate endDate = DateUtils.getBusinessLocalDate().minusDays(1);

        List<LoanDelinquencyAction> delinquencyActions = new ArrayList<>();
        List<LoanDelinquencyActionData> effectiveDelinquency = new ArrayList<>();
        CollectionData loanCollectionData = CollectionData.template();

        when(loanRepository.findOneWithNotFoundDetection(anyLong())).thenReturn(loanForProcessing);

        when(delinquencyReadPlatformService.retrieveLoanDelinquencyActions(anyLong())).thenReturn(delinquencyActions);
        LoanDelinquencyAction backdatedPauseAction = Mockito.mock(LoanDelinquencyAction.class);
        backdatedPauseAction.setId(1L);

        when(delinquencyActionParseAndValidator.validateAndParseUpdate(command, loanForProcessing, delinquencyActions,
                DateUtils.getBusinessLocalDate())).thenReturn(backdatedPauseAction);
        when(backdatedPauseAction.getStartDate()).thenReturn(startDate);
        when(backdatedPauseAction.getEndDate()).thenReturn(endDate);
        when(backdatedPauseAction.getAction()).thenReturn(DelinquencyAction.PAUSE);

        when(loanDelinquencyActionRepository.saveAndFlush(backdatedPauseAction)).thenReturn(backdatedPauseAction);

        when(delinquencyEffectivePauseHelper.calculateEffectiveDelinquencyList(delinquencyActions)).thenReturn(effectiveDelinquency);
        when(loanDelinquencyDomainService.getOverdueCollectionData(any(), anyList())).thenReturn(loanCollectionData);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());

        // when
        underTest.createDelinquencyAction(loanForProcessing.getId(), command);

        // then
        // verify event is raised
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyPauseChangeEvent.capture());

        Loan loanPayloadForEvent = loanDelinquencyPauseChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);

        // verify no range change event for pause flag change as both start and end date are backdated
        verify(businessEventNotifierService, times(0)).notifyPostBusinessEvent(any(LoanDelinquencyRangeChangeBusinessEvent.class));

    }

    @Test
    public void givenLoanAccountWhenBackdatedPauseActionThenLoanDelinquencyRangeChangeBusinessEventIsRaisedIfPauseFlagChangeTest() {
        ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDelinquencyRangeChangeEvent = ArgumentCaptor
                .forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
        // given
        Loan loanForProcessing = Mockito.mock(Loan.class);
        loanForProcessing.setId(1L);

        JsonCommand command = Mockito.mock(JsonCommand.class);

        // Pause period
        LocalDate startDate = DateUtils.getBusinessLocalDate().minusDays(2);
        LocalDate endDate = DateUtils.getBusinessLocalDate().plusDays(10);

        List<LoanDelinquencyAction> delinquencyActions = new ArrayList<>();
        List<LoanDelinquencyActionData> effectiveDelinquency = new ArrayList<>();
        CollectionData loanCollectionData = CollectionData.template();

        when(loanRepository.findOneWithNotFoundDetection(anyLong())).thenReturn(loanForProcessing);

        when(delinquencyReadPlatformService.retrieveLoanDelinquencyActions(anyLong())).thenReturn(delinquencyActions);
        LoanDelinquencyAction backdatedPauseAction = Mockito.mock(LoanDelinquencyAction.class);
        backdatedPauseAction.setId(1L);

        when(delinquencyActionParseAndValidator.validateAndParseUpdate(command, loanForProcessing, delinquencyActions,
                DateUtils.getBusinessLocalDate())).thenReturn(backdatedPauseAction);
        when(backdatedPauseAction.getStartDate()).thenReturn(startDate);
        when(backdatedPauseAction.getEndDate()).thenReturn(endDate);
        when(backdatedPauseAction.getAction()).thenReturn(DelinquencyAction.PAUSE);

        when(loanDelinquencyActionRepository.saveAndFlush(backdatedPauseAction)).thenReturn(backdatedPauseAction);

        when(delinquencyEffectivePauseHelper.calculateEffectiveDelinquencyList(delinquencyActions)).thenReturn(effectiveDelinquency);
        when(loanDelinquencyDomainService.getOverdueCollectionData(any(), anyList())).thenReturn(loanCollectionData);
        when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());

        // when
        underTest.createDelinquencyAction(loanForProcessing.getId(), command);

        // then
        // verify event is raised
        verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyRangeChangeEvent.capture());

        Loan loanPayloadForEvent = loanDelinquencyRangeChangeEvent.getValue().get();
        assertEquals(loanForProcessing, loanPayloadForEvent);
    }

}
