package zielu.gittoolbox.status;

import com.intellij.openapi.util.Key;
import com.intellij.vcs.log.Hash;
import git4idea.commands.GitLineHandlerListener;
import org.jetbrains.annotations.Nullable;
import zielu.gittoolbox.util.GtUtil;

public class GitRevListLeftRightCounter implements GitLineHandlerListener {
  private int ahead = 0;
  private Hash aheadHash;
  private int behind = 0;
  private Hash behindHash;

  private int exitCode;
  @Nullable
  private Throwable error;

  @Override
  public void onLineAvailable(String line, Key outputType) {
    if (aheadLine(line)) {
      onAheadLine(line);
    } else if (behindLine(line)) {
      onBehindLine(line);
    }
  }

  private void onAheadLine(String line) {
    ahead++;
    if (aheadHash == null) {
      aheadHash = hashFromLine(line);
    }
  }

  private void onBehindLine(String line) {
    behind++;
    if (behindHash == null) {
      behindHash = hashFromLine(line);
    }
  }

  private boolean aheadLine(String line) {
    return line.startsWith("<");
  }

  private boolean behindLine(String line) {
    return line.startsWith(">");
  }

  private Hash hashFromLine(String line) {
    return GtUtil.hash(line.substring(1));
  }

  public int ahead() {
    return ahead;
  }

  public int behind() {
    return behind;
  }

  @Nullable
  public Hash aheadTop() {
    return aheadHash;
  }

  @Nullable
  public Hash behindTop() {
    return behindHash;
  }

  public boolean isSuccess() {
    return exitCode == 0 && error == null;
  }

  @Override
  public void processTerminated(int exitCode) {
    this.exitCode = exitCode;
  }

  @Override
  public void startFailed(Throwable throwable) {
    error = throwable;
  }
}

@@ -148,16 +148,118 @@
 stener;%0A
+import java.util.concurrent.atomic.AtomicInteger;%0Aimport java.util.concurrent.atomic.AtomicReference;%0A
 import o
@@ -421,37 +421,94 @@
 ate 
+f
 in
-t ahead = 0;%0A  private 
+al AtomicInteger ahead = new AtomicInteger();%0A  private final AtomicReference%3C
 Hash
+%3E
  ahe
@@ -509,24 +509,50 @@
 h%3E aheadHash
+ = new AtomicReference%3C%3E()
 ;%0A  private 
@@ -555,38 +555,95 @@
 ate 
+f
 in
-t behind = 0;%0A  private 
+al AtomicInteger behind = new AtomicInteger();%0A  private final AtomicReference%3C
 Hash
+%3E
  beh
@@ -649,16 +649,42 @@
 hindHash
+ = new AtomicReference%3C%3E()
 ;%0A%0A  pri
@@ -990,18 +990,34 @@
    ahead
-++
+.incrementAndGet()
 ;%0A    if
@@ -1023,24 +1023,30 @@
 f (aheadHash
+.get()
  == null) %7B%0A
@@ -1056,27 +1056,29 @@
    aheadHash
- = 
+.set(
 hashFromLine
@@ -1075,32 +1075,33 @@
 shFromLine(line)
+)
 ;%0A    %7D%0A  %7D%0A%0A  p
@@ -1154,10 +1154,26 @@
 hind
-++
+.incrementAndGet()
 ;%0A  
@@ -1188,16 +1188,22 @@
 hindHash
+.get()
  == null
@@ -1222,19 +1222,21 @@
 hindHash
- = 
+.set(
 hashFrom
@@ -1237,32 +1237,33 @@
 shFromLine(line)
+)
 ;%0A    %7D%0A  %7D%0A%0A  p
@@ -1552,16 +1552,22 @@
 rn ahead
+.get()
 ;%0A  %7D%0A%0A 
@@ -1606,16 +1606,22 @@
 n behind
+.get()
 ;%0A  %7D%0A%0A 
@@ -1674,24 +1674,30 @@
 rn aheadHash
+.get()
 ;%0A  %7D%0A%0A  @Nu
@@ -1752,16 +1752,22 @@
 hindHash
+.get()
 ;%0A  %7D%0A%0A 

Make thread-safe