// Copyright 2004-present Facebook. All Rights Reserved.

package com.facebook.react.bridge;

import javax.annotation.Nullable;

import com.facebook.proguard.annotations.DoNotStrip;

/**
 * Static class that allows markers to be placed in React code and responded to in a
 * configurable way
 */
@DoNotStrip
public class ReactMarker {

  public interface MarkerListener {
    void logMarker(ReactMarkerConstants name, @Nullable String tag, int instanceKey);
  };

  private static @Nullable MarkerListener sMarkerListener = null;

  public static void initialize(MarkerListener listener) {
    if (sMarkerListener == null) {
      sMarkerListener = listener;
    }
  }

  @DoNotStrip
  public static void clearMarkerListener() {
    sMarkerListener = null;
  }

  @DoNotStrip
  public static void logMarker(String name) {
    logMarker(name, null);
  }

  @DoNotStrip
  public static void logMarker(String name, int instanceKey) {
    logMarker(name, null, instanceKey);
  }

  @DoNotStrip
  public static void logMarker(String name, @Nullable String tag) {
    logMarker(name, tag, 0);
  }

  @DoNotStrip
  public static void logMarker(String name, @Nullable String tag, int instanceKey) {
    if (sMarkerListener != null) {
      sMarkerListener.logMarker(ReactMarkerConstants.valueOf(name), tag, instanceKey);
    }
  }

  @DoNotStrip
  public static void logMarker(ReactMarkerConstants name) {
    logMarker(name, null, 0);
  }

  @DoNotStrip
  public static void logMarker(ReactMarkerConstants name, int instanceKey) {
    logMarker(name, null, instanceKey);
  }

  @DoNotStrip
  public static void logMarker(ReactMarkerConstants name, @Nullable String tag) {
    logMarker(name, null, 0);
  }

  @DoNotStrip
  public static void logMarker(ReactMarkerConstants name, @Nullable String tag, int instanceKey) {
    if (sMarkerListener != null) {
      sMarkerListener.logMarker(name, tag, instanceKey);
    }
  }
}

@@ -83,24 +83,76 @@
 ct.bridge;%0A%0A
+import java.util.List;%0Aimport java.util.ArrayList;%0A%0A
 import javax
@@ -509,16 +509,185 @@
 ;%0A  %7D;%0A%0A
+  // Use a list instead of a set here because we expect the number of listeners%0A  // to be very small, and we want listeners to be called in a deterministic%0A  // order.%0A
   privat
@@ -695,26 +695,27 @@
  static 
-@Nullable 
+final List%3C
 MarkerLi
@@ -720,32 +720,27 @@
 Listener
+%3E
  s
-Marker
 Listener
  = null;
@@ -731,25 +731,53 @@
 Listener
+s
  = n
-ull;%0A
+ew ArrayList%3C%3E();%0A%0A  @DoNotStrip
 %0A  publi
@@ -794,18 +794,19 @@
 oid 
-initialize
+addListener
 (Mar
@@ -837,71 +837,276 @@
     
-if (sMarkerL
+synchronized(sListeners) %7B%0A      if (sListeners.indexOf(l
 istener
+)
  == 
-null) %7B%0A      sMarkerListener = 
+-1) %7B%0A        sListeners.add(listener);%0A      %7D%0A    %7D%0A  %7D%0A%0A  @DoNotStrip%0A  public static void removeListener(MarkerListener listener) %7B%0A    synchronized(sListeners) %7B%0A      sListeners.remove(
 listener
 ;%0A  
@@ -1101,16 +1101,17 @@
 listener
+)
 ;%0A    %7D%0A
@@ -1169,16 +1169,17 @@
 Listener
+s
 () %7B%0A   
@@ -1184,30 +1184,65 @@
    s
-MarkerListener = null;
+ynchronized(sListeners) %7B%0A      sListeners.clear();%0A    %7D
 %0A  %7D
@@ -1680,71 +1680,38 @@
     
-if (sMarkerListener != null) %7B%0A      sMarkerListener.logM
+ReactMarkerConstants m
 arker
-(
+ = 
 Reac
@@ -1740,16 +1740,38 @@
 Of(name)
+;%0A    logMarker(marker
 , tag, i
@@ -1779,30 +1779,24 @@
 stanceKey);%0A
-    %7D%0A
   %7D%0A%0A  @DoNo
@@ -2281,21 +2281,54 @@
 ) %7B%0A    
-if
+synchronized(sListeners) %7B%0A      for
  (
-s
 MarkerLi
@@ -2338,15 +2338,29 @@
 ner 
-!= null
+listener : sListeners
 ) %7B%0A
@@ -2369,16 +2369,11 @@
     
-sMarkerL
+  l
 iste
@@ -2411,16 +2411,24 @@
 ceKey);%0A
+      %7D%0A
     %7D%0A  

add support for multiple bridge listeners