package org.commcare.heartbeat;

import org.javarosa.core.util.externalizable.DeserializationException;
import org.javarosa.core.util.externalizable.ExtUtil;
import org.javarosa.core.util.externalizable.ExtWrapList;
import org.javarosa.core.util.externalizable.Externalizable;
import org.javarosa.core.util.externalizable.PrototypeFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.LinkedList;

/**
 * Created by amstone326 on 2/12/18.
 */

public class UpdatePromptShowHistory implements Externalizable {

    private LinkedList<Boolean> showHistory;
    // the number of logins to keep in show history
    private int numLoginsToTrack;

    public UpdatePromptShowHistory() {
        this.numLoginsToTrack = UpdateToPrompt.getReducedShowFrequency() - 1;
        this.showHistory = new LinkedList<>();
    }

    /**
     *
     * @param showFrequency - The frequency with which we currently want to show update prompts;
     *                 if showFrequency is N, then this means "show the prompt once every N logins"
     * @return - If the prompt to whom this show history belongs should be shown right now, based
     * on the given showFrequency
     */
    boolean shouldShowOnThisLogin(int showFrequency) {
        boolean shouldShow = true;

        int numChecked = 0;
        int index = showHistory.size() - 1;
        while (index >= 0 && numChecked < showFrequency-1) {
            if (showHistory.get(index)) {
                shouldShow = false;
                break;
            }
            numChecked++;
            index--;
        }

        updateHistoryWithLatest(shouldShow);
        return shouldShow;
    }

    private void updateHistoryWithLatest(boolean lastShowValue) {
        if (isFull()) {
            showHistory.poll();
        }
        showHistory.add(lastShowValue);
    }

    private boolean isFull() {
        return showHistory.size() == numLoginsToTrack;
    }

    @Override
    public void readExternal(DataInputStream in, PrototypeFactory pf) throws IOException, DeserializationException {
        numLoginsToTrack = ExtUtil.readInt(in);
        showHistory = (LinkedList<Boolean>)ExtUtil.read(in, new ExtWrapList(Boolean.class, LinkedList.class), pf);
    }

    @Override
    public void writeExternal(DataOutputStream out) throws IOException {
        ExtUtil.writeNumeric(out, numLoginsToTrack);
        ExtUtil.write(out, new ExtWrapList(showHistory));
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < showHistory.size(); i++) {
            sb.append(showHistory.get(i));
            sb.append(" ");
        }
        return sb.toString();
    }
}

@@ -618,211 +618,47 @@
 ry;%0A
-    // the number of logins to keep in show history%0A    private int numLoginsToTrack;%0A%0A    public UpdatePromptShowHistory() %7B%0A        this.numLoginsToTrack = UpdateToPrompt.getReducedShowFrequency() - 1;
+%0A    public UpdatePromptShowHistory() %7B
 %0A   
@@ -1707,32 +1707,439 @@
 wValue);%0A    %7D%0A%0A
+    /**%0A     * The maximum number of previous shows that the show history could ever need to know about is%0A     * 1 less than the reduced show frequency number (e.g. if the reduced show frequency is 4,%0A     * that means we need to show the prompt once every 4 logins, which means that on any given%0A     * login, we need to know about the prior 3 logins in order to decide whether or not to show it.%0A     */%0A
     private bool
@@ -2190,32 +2190,58 @@
 ze() == 
-numLoginsToTrack
+UpdateToPrompt.getReducedShowFrequency()-1
 ;%0A    %7D%0A
@@ -2376,56 +2376,8 @@
 n %7B%0A
-        numLoginsToTrack = ExtUtil.readInt(in);%0A
     
@@ -2500,32 +2500,32 @@
 %0A%0A    @Override%0A
+
     public void 
@@ -2585,61 +2585,8 @@
 n %7B%0A
-        ExtUtil.writeNumeric(out, numLoginsToTrack);%0A
     

remove need to store numLoginsToTrack as a variable