<commit_before>package com.dataart.android.devicehive.client;

import java.util.LinkedList;
import java.util.List;

import android.content.Context;

import com.dataart.android.devicehive.Command;
import com.dataart.android.devicehive.DeviceData;
import com.dataart.android.devicehive.Notification;
import com.dataart.android.devicehive.client.commands.NotificationsRetrivalCommand;
import com.dataart.android.devicehive.client.commands.PollMultipleDeviceNotificationsCommand;
import com.dataart.android.devicehive.client.commands.PollMultipleDeviceNotificationsCommand.DeviceNotification;

/**
 * Represents a device client which provides high-level API for communication
 * and receive notifications from several devices. This class is abstract and
 * designed to be subclassed in order to handle incoming notifications. Also
 * this class provides a number of various callbacks:
 * {@link #onStartReceivingNotifications()},
 * {@link #onStopReceivingNotifications()},
 * {@link #onStartSendingCommand(Command)},
 * {@link #onFinishSendingCommand(Command)},
 * {@link #onFailSendingCommand(Command)}, etc.
 * 
 */
public abstract class MultipleDeviceClient extends DeviceClient {

	private List<DeviceData> devices;

	/**
	 * Construct client with given {@link Context} and {@link DeviceData}
	 * objects.
	 * 
	 * @param context
	 *            {@link Context} object. In most cases this should be
	 *            application context which stays alive during the entire life
	 *            of an application.
	 * @param deviceData
	 *            {@link DeviceData} object which describes device to
	 *            communicate with.
	 */
	public MultipleDeviceClient(Context context, final List<DeviceData> devices) {
		super(context);
		this.devices = devices;
		setServiceConnection(new MultipleDeviceClientServiceConnection(context));
	}

	private class MultipleDeviceClientServiceConnection extends
			ClientServiceConnection {

		public MultipleDeviceClientServiceConnection(Context context) {
			super(context);
		}

		@Override
		protected NotificationsRetrivalCommand getPollNotificationsCommand(
				String lastNotificationPollTimestamp) {
			return new PollMultipleDeviceNotificationsCommand(getDeviceGuids(),
					lastNotificationPollTimestamp);
		}

		@Override
		protected void didReceiveNotification(Notification notification) {
			DeviceNotification deviceNotification = (DeviceNotification) notification;
			onReceiveNotification(deviceNotification.getDeviceGuid(),
					notification);
		}

		private List<String> getDeviceGuids() {
			if (devices != null && !devices.isEmpty()) {
				final List<String> guids = new LinkedList<String>();
				for (DeviceData device : devices) {
					guids.add(device.getId());
				}
				return guids;
			} else {
				return null;
			}
		}
	}

	/**
	 * Send command to the given device.
	 * 
	 * @param device Target device.
	 * @param command
	 *            {@link Command} to be sent.
	 */
	public void sendCommand(DeviceData device, final Command command) {
		this.sendCommand(device, command);
	}

	/**
	 * Reload device data. Current device data is updated with instance of
	 * {@link DeviceData} retrieved from the server.
	 * 
	 * @see #onFinishReloadingDeviceData(DeviceData)
	 * @see #onFailReloadingDeviceData()
	 */
	public void reloadDeviceData(DeviceData device) {
		serviceConnection.reloadDeviceData(device);
	}

	/* package */void onReloadDeviceDataFinishedInternal(DeviceData deviceData) {
		// TODO: update device data
		onFinishReloadingDeviceData(deviceData);
	}

	/**
	 * Handle received notification. Can be called either on main (UI) thread or
	 * some background thread depending on<commit_msg>Android framework: reload device data fix.<commit_after>package com.dataart.android.devicehive.client;

import java.util.LinkedList;
import java.util.List;

import android.content.Context;

import com.dataart.android.devicehive.Command;
import com.dataart.android.devicehive.DeviceData;
import com.dataart.android.devicehive.Notification;
import com.dataart.android.devicehive.client.commands.NotificationsRetrivalCommand;
import com.dataart.android.devicehive.client.commands.PollMultipleDeviceNotificationsCommand;
import com.dataart.android.devicehive.client.commands.PollMultipleDeviceNotificationsCommand.DeviceNotification;

/**
 * Represents a device client which provides high-level API for communication
 * and receive notifications from several devices. This class is abstract and
 * designed to be subclassed in order to handle incoming notifications. Also
 * this class provides a number of various callbacks:
 * {@link #onStartReceivingNotifications()},
 * {@link #onStopReceivingNotifications()},
 * {@link #onStartSendingCommand(Command)},
 * {@link #onFinishSendingCommand(Command)},
 * {@link #onFailSendingCommand(Command)}, etc.
 * 
 */
public abstract class MultipleDeviceClient extends DeviceClient {

	private List<DeviceData> devices;

	/**
	 * Construct client with given {@link Context} and {@link DeviceData}
	 * objects.
	 * 
	 * @param context
	 *            {@link Context} object. In most cases this should be
	 *            application context which stays alive during the entire life
	 *            of an application.
	 * @param deviceData
	 *            {@link DeviceData} object which describes device to
	 *            communicate with.
	 */
	public MultipleDeviceClient(Context context, final List<DeviceData> devices) {
		super(context);
		this.devices = devices;
		setServiceConnection(new MultipleDeviceClientServiceConnection(context));
	}

	private class MultipleDeviceClientServiceConnection extends
			ClientServiceConnection {

		public MultipleDeviceClientServiceConnection(Context context) {
			super(context);
		}

		@Override
		protected NotificationsRetrivalCommand getPollNotificationsCommand(
				String lastNotificationPollTimestamp) {
			return new PollMultipleDeviceNotificationsCommand(getDeviceGuids(),
					lastNotificationPollTimestamp);
		}

		@Override
		protected void didReceiveNotification(Notification notification) {
			DeviceNotification deviceNotification = (DeviceNotification) notification;
			onReceiveNotification(deviceNotification.getDeviceGuid(),
					notification);
		}

		private List<String> getDeviceGuids() {
			if (devices != null && !devices.isEmpty()) {
				final List<String> guids = new LinkedList<String>();
				for (DeviceData device : devices) {
					guids.add(device.getId());
				}
				return guids;
			} else {
				return null;
			}
		}
	}

	/**
	 * Send command to the given device.
	 * 
	 * @param device
	 *            Target device.
	 * @param command
	 *            {@link Command} to be sent.
	 */
	public void sendCommand(DeviceData device, final Command command) {
		this.sendCommand(device, command);
	}

	/**
	 * Reload device data. Current device data is updated with instance of
	 * {@link DeviceData} retrieved from the server.
	 * 
	 * @see #onFinishReloadingDeviceData(DeviceData)
	 * @see #onFailReloadingDeviceData()
	 */
	public void reloadDeviceData(DeviceData device) {
		serviceConnection.reloadDeviceData(device);
	}

	/* package */void onReloadDeviceDataFinishedInternal(DeviceData deviceData) {
		final DeviceData device = getDeviceDataWithId(deviceData.getId());
		devices.remove(device);
		devices.add(deviceData);
		onFinishReloadingDeviceData(deviceData);
	}

	private DeviceData getDeviceDataWithId(String deviceId) {
		for (DeviceData device : devices) {
			if (device.getId().equals(deviceId)) {
				return device;
			}
		}
		return null;
	}

	/**
	 * Handle received notification. Can be called either on main (UI) thread or
	 * some background thread depending on
{'fraction_non_alphanumeric': 0.08915032679738562, 'fraction_numerical': 0.0, 'mean_word_length': 4.418555240793201, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1377041', 'n_tokens_mistral': 2222, 'n_tokens_neox': 1974, 'n_words': 550}