/*
 * Copyright 2018 The RoboZonky Project
 *
 * 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 com.github.robozonky.app.portfolio;

import java.math.BigDecimal;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Supplier;

import com.github.robozonky.api.remote.entities.Statistics;
import com.github.robozonky.api.remote.enums.Rating;
import com.github.robozonky.api.strategies.PortfolioOverview;
import com.github.robozonky.app.authentication.Tenant;
import com.github.robozonky.common.remote.Zonky;

public class Portfolio {

    private final AtomicReference<PortfolioOverview> portfolioOverview = new AtomicReference<>();
    private final Statistics statistics;
    private final RemoteBalance balance;
    private final Supplier<BlockedAmountProcessor> blockedAmounts;

    private Portfolio(final Supplier<BlockedAmountProcessor> blockedAmounts, final Statistics statistics,
                      final Function<Portfolio, RemoteBalance> balance) {
        this.blockedAmounts = blockedAmounts;
        this.statistics = statistics;
        this.balance = balance.apply(this);
    }

    public static Portfolio create(final Tenant tenant, final Supplier<BlockedAmountProcessor> transfers) {
        return create(tenant, transfers, p -> RemoteBalance.create(tenant, p::balanceUpdated));
    }

    public static Portfolio create(final Tenant tenant, final Supplier<BlockedAmountProcessor> transfers,
                                   final Function<Portfolio, RemoteBalance> balance) {
        return new Portfolio(transfers, tenant.call(Zonky::getStatistics), balance);
    }

    public void simulateCharge(final int loanId, final Rating rating, final BigDecimal amount) {
        blockedAmounts.get().simulateCharge(loanId, rating, amount);
        balance.update(amount.negate()); // will result in balanceUpdated() getting called
    }

    public void balanceUpdated(final BigDecimal newBalance) {
        portfolioOverview.set(null); // reset overview, so that it could be recalculated on-demand
    }

    public RemoteBalance getRemoteBalance() {
        return balance;
    }

    public PortfolioOverview getOverview() {
        return portfolioOverview.updateAndGet(po -> {
            if (po == null) {
                return PortfolioOverview.calculate(balance.get(), statistics, blockedAmounts.get().getAdjustments(),
                                                   Delinquencies.getAmountsAtRisk());
            }
            return po;
        });
    }
}

@@ -1081,33 +1081,174 @@
 ky;%0A
-%0Apublic class Portfolio %7B
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Apublic class Portfolio %7B%0A%0A    private static final Logger LOGGER = LoggerFactory.getLogger(Portfolio.class);
 %0A%0A  
@@ -2622,32 +2622,64 @@
 l newBalance) %7B%0A
+        LOGGER.debug(%22Reset.%22);%0A
         portfoli
@@ -2761,16 +2761,16 @@
 -demand%0A
-
     %7D%0A%0A 
@@ -2990,22 +2990,50 @@
         
-return
+final PortfolioOverview overview =
  Portfol
@@ -3079,16 +3079,95 @@
 tistics,
+%0A                                                                              
  blocked
@@ -3249,16 +3249,44 @@
         
+    
+                        
 Delinque
@@ -3308,24 +3308,116 @@
 sAtRisk());%0A
+                LOGGER.debug(%22Calculated: %7B%7D.%22, overview);%0A                return overview;%0A
             

Add logging to portfolio overview