package bisq.daemon.grpc.interceptor;

import bisq.common.Timer;
import bisq.common.UserThread;

import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.TimeUnit;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

import static java.lang.String.format;

@Slf4j
public final class GrpcCallRateMeter {

    @Getter
    private final int allowedCallsPerTimeUnit;
    @Getter
    private final TimeUnit timeUnit;

    @Getter
    private int callsCount = 0;

    @Getter
    private boolean isRunning;

    @Nullable
    private Timer timer;

    public GrpcCallRateMeter(int allowedCallsPerTimeUnit, TimeUnit timeUnit) {
        this.allowedCallsPerTimeUnit = allowedCallsPerTimeUnit;
        this.timeUnit = timeUnit;
    }

    public void start() {
        if (timer != null)
            timer.stop();

        timer = UserThread.runPeriodically(() -> callsCount = 0, 1, timeUnit);
        isRunning = true;
    }

    public void incrementCallsCount() {
        callsCount++;
    }

    public boolean isCallRateExceeded() {
        return callsCount > allowedCallsPerTimeUnit;
    }

    public String getCallsCountProgress(String calledMethodName) {
        String shortTimeUnitName = StringUtils.chop(timeUnit.name().toLowerCase());
        return format("%s has been called %d time%s in the last %s;  the rate limit is %d/%s.",
                calledMethodName,
                callsCount,
                callsCount == 1 ? "" : "s",
                shortTimeUnitName,
                allowedCallsPerTimeUnit,
                shortTimeUnitName);
    }
}

@@ -1,8 +1,690 @@
+/*%0A * This file is part of Bisq.%0A *%0A * Bisq is free software: you can redistribute it and/or modify it%0A * under the terms of the GNU Affero General Public License as published by%0A * the Free Software Foundation, either version 3 of the License, or (at%0A * your option) any later version.%0A *%0A * Bisq is distributed in the hope that it will be useful, but WITHOUT%0A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or%0A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public%0A * License for more details.%0A *%0A * You should have received a copy of the GNU Affero General Public License%0A * along with Bisq. If not, see %3Chttp://www.gnu.org/licenses/%3E.%0A */%0A%0A
 package 
@@ -1144,17 +1144,16 @@
 meUnit;%0A
-%0A
     @Get
@@ -1188,17 +1188,16 @@
 nt = 0;%0A
-%0A
     @Get
@@ -1212,16 +1212,26 @@
 private 
+transient 
 boolean 
@@ -1504,53 +1504,16 @@
     
-if (timer != null)%0A            timer.
 stop();%0A
 %0A   
@@ -1508,17 +1508,16 @@
 stop();%0A
-%0A
         
@@ -1612,32 +1612,145 @@
  = true;%0A    %7D%0A%0A
+    public void stop() %7B%0A        if (timer != null)%0A            timer.stop();%0A%0A        isRunning = false;%0A    %7D%0A%0A
     public void 
@@ -2125,14 +2125,9 @@
 t %25s
-;  the
+,
  rat
@@ -2142,17 +2142,16 @@
 is %25d/%25s
-.
 %22,%0A     
@@ -2368,11 +2368,335 @@
 );%0A    %7D
+%0A%0A    @Override%0A    public String toString() %7B%0A        return %22GrpcCallRateMeter%7B%22 +%0A                %22allowedCallsPerTimeUnit=%22 + allowedCallsPerTimeUnit +%0A                %22, timeUnit=%22 + timeUnit.name() +%0A                %22, callsCount=%22 + callsCount +%0A                %22, isRunning=%22 + isRunning +%0A                '%7D';%0A    %7D
 %0A%7D%0A

Add license comment, stop & toString methods, and make isRunning transient