package eu.toolchain.ffwd;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.spotify.ffwd.protocol0.Protocol0;
import com.spotify.ffwd.protocol0.Protocol0.Attribute;
@RequiredArgsConstructor
@EqualsAndHashCode(of = { "has", "time", "key", "value", "host", "state",
"description", "ttl", "tags", "attributes" })
public class Event {
private static final List<String> EMPTY_TAGS = new ArrayList<String>();
private static final Map<String, String> EMPTY_ATTRIBUTES = new HashMap<String, String>();
public static final long TIME = 1 << 0;
public static final long KEY = 1 << 1;
public static final long VALUE = 1 << 2;
public static final long HOST = 1 << 3;
public static final long STATE = 1 << 4;
public static final long DESCRIPTION = 1 << 5;
public static final long TTL = 1 << 6;
public static final long TAGS = 1 << 7;
public static final long ATTRIBUTES = 1 << 8;
private final long has;
@Getter
private final long time;
@Getter
private final String key;
@Getter
private final double value;
@Getter
private final String host;
@Getter
private final String state;
@Getter
private final String description;
@Getter
private final long ttl;
@Getter
private final List<String> tags;
@Getter
private final Map<String, String> attributes;
public Event() {
this.has = 0;
this.time = 0;
this.key = null;
this.value = 0;
this.host = null;
this.state = null;
this.description = null;
this.ttl = 0;
this.tags = EMPTY_TAGS;
this.attributes = EMPTY_ATTRIBUTES;
}
private boolean test(long n) {
return (has & n) != 0;
}
private long set(long n) {
return has | n;
}
public Event time(long time) {
return new Event(set(TIME), time, key, value, host, state, description,
ttl, tags, attributes);
}
public Event key(String key) {
return new Event(set(KEY), time, key, value, host, state, description,
ttl, tags, attributes);
}
public Event value(double value) {
return new Event(set(VALUE), time, key, value, host, state,
description, ttl, tags, attributes);
}
public Event host(String host) {
return new Event(set(HOST), time, key, value, host, state, description,
ttl, tags, attributes);
}
public Event state(String state) {
return new Event(set(STATE), time, key, value, host, state,
description, ttl, tags, attributes);
}
public Event description(String description) {
return new Event(set(DESCRIPTION), time, key, value, host, state,
description, ttl, tags, attributes);
}
public Event ttl(long ttl) {
return new Event(set(TTL), time, key, value, host, state, description,
ttl, tags, attributes);
}
public Event tag(String tag) {
final List<String> tags = new ArrayList<String>(this.tags);
tags.add(tag);
return new Event(set(TAGS), time, key, value, host, state, description,
ttl, tags, attributes);
}
public Event tags(List<String> tags) {
return new Event(set(TAGS), time, key, value, host, state, description,
ttl, new ArrayList<String>(tags), attributes);
}
public Event attribute(String k, String v) {
final Map<String, String> attributes = new HashMap<String, String>(
this.attributes);
attributes.put(k, v);
return new Event(set(ATTRIBUTES), time, key, value, host, state,
description, ttl, tags, attributes);
}
public Event attributes(Map<String, String> attributes) {
return new Event(set(ATTRIBUTES), time, key, value, host, state,
description, ttl, tags, new HashMap<String, String>(attributes));
}
public byte[] serialize() {
final Protocol0.Event.Builder builder = Protocol0.Event.newBuilder();
if (test(TIME))
builder.setTime(time);
if (test(KEY))
builder.setKey(key);
if (test(VALUE))
builder.setValue(value);
if (test(HOST))
builder.setHost(host);
if (test(STATE))
builder.setState(host);
if (test(DESCRIPTION))
builder.setDescription(description);
if (test(TTL))
builder.setTtl(ttl);
if (test(TAGS)) {
for (final String tag : tags) {
builder.addTags(tag);
}
}
if (test(ATTRIBUTES)) {
for (final Map.Entry<String, String> entry : attributes.entrySet()) {
if (entry.getKey() == null)
continue;
final Attribute.Builder attributeBuilder = Protocol0.Attribute.newBuilder().setKey(entry.getKey());
if (entry.getValue() != null)
attributeBuilder.setValue(entry.getValue());
builder.addAttributes(attributeBuilder.build());
}
}
final Protocol0.Event e = builder.build();
return Protocol0.Message.newBuilder().setEvent(e).build().toByteArray();
}
}