package org.yamcs.web.rest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yamcs.api.MediaType;
import org.yamcs.web.HttpException;
import org.yamcs.web.InternalServerErrorException;
import org.yamcs.web.WebConfig;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.channel.ChannelFuture;
/**
* provides information about available displays
*
* Currently the only method supported is "list"
* @author nm
*
*/
public class DisplayRestHandler extends RestHandler {
JsonFactory jsonFactory=new JsonFactory();
private final static Logger log=LoggerFactory.getLogger(DisplayRestHandler.class);
@Route(path="/api/displays/:instance", method="GET")
public void listDisplays(RestRequest req) throws HttpException {
String instance = verifyInstance(req, req.getRouteParam("instance"));
ByteBuf cb=req.getChannelHandlerContext().alloc().buffer(1024);
ByteBufOutputStream cbos=new ByteBufOutputStream(cb);
try (JsonGenerator json = jsonFactory.createGenerator(cbos, JsonEncoding.UTF8)) {
json.writeStartArray();
File displayDir = null;
for (String webRoot : WebConfig.getInstance().getWebRoots()) {
File dir = new File(webRoot + File.separator + instance + File.separator + "displays");
if (dir.exists()) {
displayDir = dir;
break;
}
}
if (displayDir != null) {
writeFilesFromDir(json, new Path(), displayDir);
}
json.close();
completeOK(req, MediaType.JSON, cb);
} catch (IOException e) {
throw new InternalServerErrorException(e);
}
}
private void writeFilesFromDir(JsonGenerator json, Path path, File f) throws JsonGenerationException, IOException {
if(!f.isDirectory()) {
log.warn("Supposed to list all files from '{}' but it's not a directory", f);
return;
}
//all this complicated stack in order to not write empty directories and not have an intermediate tree to store the result
File[] files=f.listFiles();
for(File f1: files) {
if(f1.isDirectory()) {
path.push(f1.getName());
writeFilesFromDir(json, path, f1);
path.pop();
} else if(f1.getName().endsWith(".uss")){
if(path.index<path.size()) {
while(path.index < path.size()) {
json.writeStartArray();
json.writeString(path.get(path.index));
path.index++;
}
}
json.writeString(f1.getName());
}
}
while(path.index>=path.size()) {
json.writeEndArray();
path.index--;
}
}
private static class Path {
int index=0;
ArrayList<String> list=new ArrayList<>();
public void push(String name) {
list.add(name);
}
public String get(int idx) {
return list.get(idx);
}
public int size() {
return list.size();
}
public void pop() {
list.remove(list.size()-1);
}
}
}