// Copyright © 2017 DWANGO Co., Ltd.
package jp.co.dwango.cbb.db;

import org.json.JSONArray;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class DataBus {
	private final List<DataBusHandler> handlers = Collections.synchronizedList(new ArrayList<DataBusHandler>());
	protected boolean destroyed = false;

	public static void logging(boolean enabled) {
		Logger.enabled = enabled;
	}

	public abstract void send(final JSONArray args);

	public void addHandler(DataBusHandler handler) {
		if (destroyed) {
			Logger.e("already destroyed");
			return;
		}
		if (0 <= handlers.indexOf(handler)) {
			return;
		}
		handlers.add(handler);
	}

	public void removeHandler(DataBusHandler handler) {
		if (destroyed) {
			Logger.e("already destroyed");
			return;
		}
		while (handlers.contains(handler)) {
			handlers.remove(handler);
		}
	}

	public void removeAllHandlers() {
		if (destroyed) {
			Logger.e("already destroyed");
			return;
		}
		handlers.clear();
	}

	public int getHandlerCount() {
		if (destroyed) {
			Logger.e("already destroyed");
			return 0;
		}
		return handlers.size();
	}

	protected void received(JSONArray data) {
		for (DataBusHandler h : handlers) {
			h.onReceive(data);
		}
	}

	public void destroy() {
		if (!destroyed) {
			removeAllHandlers();
			destroyed = true;
		}
	}

	@Override
	protected void finalize() throws Throwable {
		try {
			super.finalize();
		} finally {
			destroy();
		}
	}
}

@@ -202,16 +202,61 @@
 taBus %7B%0A
+%09private final Object locker = new Object();%0A
 %09private
@@ -644,16 +644,43 @@
 rn;%0A%09%09%7D%0A
+%09%09synchronized (locker) %7B%0A%09
 %09%09if (0 
@@ -710,24 +710,25 @@
 dler)) %7B%0A%09%09%09
+%09
 return;%0A%09%09%7D%0A
@@ -717,34 +717,36 @@
 %7B%0A%09%09%09%09return;%0A%09%09
+%09
 %7D%0A
+%09
 %09%09handlers.add(h
@@ -754,16 +754,20 @@
 ndler);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09pub
@@ -883,16 +883,43 @@
 rn;%0A%09%09%7D%0A
+%09%09synchronized (locker) %7B%0A%09
 %09%09while 
@@ -948,24 +948,25 @@
 dler)) %7B%0A%09%09%09
+%09
 handlers.rem
@@ -971,32 +971,37 @@
 emove(handler);%0A
+%09%09%09%7D%0A
 %09%09%7D%0A%09%7D%0A%0A%09public 
@@ -1095,16 +1095,43 @@
 rn;%0A%09%09%7D%0A
+%09%09synchronized (locker) %7B%0A%09
 %09%09handle
@@ -1138,24 +1138,28 @@
 rs.clear();%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09public 
@@ -1325,16 +1325,111 @@
 data) %7B%0A
+%09%09if (destroyed) %7B%0A%09%09%09Logger.e(%22already destroyed%22);%0A%09%09%09return;%0A%09%09%7D%0A%09%09synchronized (locker) %7B%0A%09
 %09%09for (D
@@ -1461,16 +1461,17 @@
 s) %7B%0A%09%09%09
+%09
 h.onRece
@@ -1481,16 +1481,21 @@
 (data);%0A
+%09%09%09%7D%0A
 %09%09%7D%0A%09%7D%0A%0A

support multi-thread