package fr.jcgay.notification.notifier.anybar;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import fr.jcgay.notification.Application;
import fr.jcgay.notification.DiscoverableNotifier;
import fr.jcgay.notification.Icon;
import fr.jcgay.notification.IconFileWriter;
import fr.jcgay.notification.Notification;
import fr.jcgay.notification.Notifier;
import org.slf4j.Logger;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import static org.slf4j.LoggerFactory.getLogger;
public class AnyBarNotifier implements DiscoverableNotifier {
private static final Logger LOGGER = getLogger(AnyBarNotifier.class);
private final Application application;
private final AnyBarConfiguration configuration;
private final IconFileWriter iconWriter;
private final DatagramSocket socket;
private boolean isInitialized;
@VisibleForTesting
AnyBarNotifier(Application application, AnyBarConfiguration configuration, DatagramSocket socket, IconFileWriter iconWriter) {
LOGGER.debug("Configuring AnyBar for application {}: {}.", application, configuration);
this.socket = socket;
this.iconWriter = iconWriter;
this.application = application;
this.configuration = configuration;
}
public static AnyBarNotifier create(Application application, AnyBarConfiguration configuration) {
try {
return new AnyBarNotifier(application, configuration, new DatagramSocket(), new AnyBarIconWriter());
} catch (SocketException e) {
throw new AnyBarException("Error while initiating connection with AnyBar", e);
}
}
@Override
public Notifier init() {
if (isInitialized) {
return this;
}
try {
if (application.timeout() > 0) {
socket.setSoTimeout((int) application.timeout());
}
} catch (java.io.IOException e) {
throw new AnyBarException("Error while setting socket timeout", e);
}
changeIcon(application.icon());
isInitialized = true;
return this;
}
@Override
public void send(Notification notification) {
changeIcon(notification.icon());
}
@Override
public void close() {
socket.close();
}
@Override
public boolean isPersistent() {
return true;
}
@Override
public boolean tryInit() {
return false;
}
private void changeIcon(Icon icon) {
iconWriter.write(icon);
byte[] data = icon.id().getBytes();
try {
socket.send(new DatagramPacket(data, data.length, InetAddress.getByName(configuration.host()), configuration.port()));
} catch (IOException e) {
throw new AnyBarException("Error while changing AnyBar icon", e);
}
}
@Override
public int hashCode() {
return Objects.hashCode(application, configuration);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final AnyBarNotifier other = (AnyBarNotifier) obj;
return Objects.equal(this.application, other.application)
&& Objects.equal(this.configuration, other.configuration);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("configuration", configuration)
.add("application", application)
.toString();
}
}