package org.netmelody.cieye.server.response.responder;
import static java.lang.Math.min;
import java.io.IOException;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import org.netmelody.cieye.core.domain.Feature;
import org.netmelody.cieye.core.domain.Landscape;
import org.netmelody.cieye.core.domain.LandscapeObservation;
import org.netmelody.cieye.server.CiSpyIntermediary;
import org.netmelody.cieye.server.TargetGroupBriefing;
import org.netmelody.cieye.server.response.CiEyeResponder;
import org.netmelody.cieye.server.response.CiEyeResponse;
import org.netmelody.cieye.server.response.JsonTranslator;
import org.netmelody.cieye.server.response.Prison;
import org.simpleframework.http.Request;
public final class LandscapeObservationResponder implements CiEyeResponder {
private final CiSpyIntermediary spyIntermediary;
private final Landscape landscape;
private final Prison prison;
private final Function<LandscapeObservation, LandscapeObservation> converter;
public LandscapeObservationResponder(Landscape landscape, CiSpyIntermediary spyIntermediary, Prison prison) {
this(landscape, spyIntermediary, prison, Functions.<LandscapeObservation>identity());
}
public LandscapeObservationResponder(Landscape landscape, CiSpyIntermediary spyIntermediary, Prison prison, Function<LandscapeObservation, LandscapeObservation> converter) {
this.landscape = landscape;
this.spyIntermediary = spyIntermediary;
this.prison = prison;
this.converter = converter;
}
public CiEyeResponse respond(Request request) throws IOException {
LandscapeObservation result = new LandscapeObservation();
long timeToLiveMillis = Long.MAX_VALUE;
for (Feature feature : landscape.features()) {
final TargetGroupBriefing briefing = spyIntermediary.briefingOn(feature);
result = result.add(briefing.status);
timeToLiveMillis = min(timeToLiveMillis, briefing.millisecondsUntilNextUpdate);
}
if (prison.crimeReported(landscape)) {
result = result.withDoh(prison.prisonersFor(landscape));
}
return CiEyeResponse.withJson(new JsonTranslator().toJson(converter.apply(result))).expiringInMillis(timeToLiveMillis);
}
}