package org.yamcs.web.websocket;

import org.yamcs.Processor;
import org.yamcs.ProcessorException;
import org.yamcs.cmdhistory.CommandHistoryConsumer;
import org.yamcs.cmdhistory.CommandHistoryFilter;
import org.yamcs.cmdhistory.CommandHistoryRequestManager;
import org.yamcs.commanding.PreparedCommand;
import org.yamcs.parameter.Value;
import org.yamcs.protobuf.Commanding.CommandHistoryAttribute;
import org.yamcs.protobuf.Commanding.CommandHistoryEntry;
import org.yamcs.protobuf.Commanding.CommandId;
import org.yamcs.protobuf.Yamcs.ProtoDataType;
import org.yamcs.utils.ValueUtility;

/**
 * Provides realtime command history subscription via web.
 */
public class CommandHistoryResource implements WebSocketResource, CommandHistoryConsumer {

    public static final String RESOURCE_NAME = "cmdhistory";

    private ConnectedWebSocketClient client;

    private CommandHistoryFilter subscription;
    private CommandHistoryRequestManager commandHistoryRequestManager;

    public CommandHistoryResource(ConnectedWebSocketClient client) {
        this.client = client;
        Processor processor = client.getProcessor();
        if (processor != null && processor.hasCommanding()) {
            commandHistoryRequestManager = processor.getCommandHistoryManager();
        }
    }

    @Override
    public WebSocketReply subscribe(WebSocketDecodeContext ctx, WebSocketDecoder decoder) throws WebSocketException {
        if (commandHistoryRequestManager != null) {
            subscription = commandHistoryRequestManager.subscribeCommandHistory(null, 0, this);
        }
        return WebSocketReply.ack(ctx.getRequestId());
    }

    @Override
    public WebSocketReply unsubscribe(WebSocketDecodeContext ctx, WebSocketDecoder decoder) throws WebSocketException {
        return null;
    }

    @Override
    public void unselectProcessor() {
        if (subscription != null) {
            if (commandHistoryRequestManager != null) {
                commandHistoryRequestManager.unsubscribeCommandHistory(subscription.subscriptionId);
            }
        }
        commandHistoryRequestManager = null;
    }

    @Override
    public void selectProcessor(Processor processor) throws ProcessorException {
        if (processor.hasCommanding()) {
            commandHistoryRequestManager = processor.getCommandHistoryManager();
            if (commandHistoryRequestManager != null && subscription != null) {
                commandHistoryRequestManager.addSubscription(subscription, this);
            }
        }
    }

    @Override
    public void addedCommand(PreparedCommand pc) {
        CommandHistoryEntry entry = CommandHistoryEntry.newBuilder().setCommandId(pc.getCommandId())
                .addAllAttr(pc.getAttributes()).build();
        client.sendData(ProtoDataType.CMD_HISTORY, entry);
    }

    @Override
    public void updatedCommand(CommandId cmdId, long changeDate, String key, Value value) {
        CommandHistoryAttribute cha = CommandHistoryAttribute.newBuilder().setName(key)
                .setValue(ValueUtility.toGbp(value)).build();
        CommandHistoryEntry entry = CommandHistoryEntry.newBuilder().setCommandId(cmdId).addAttr(cha).build();
        client.sendData(ProtoDataType.CMD_HISTORY, entry);
    }

    @Override
    public void socketClosed() {
        if (subscription != null && commandHistoryRequestManager != null) {
            commandHistoryRequestManager.unsubscribeCommandHistory(subscription.subscriptionId);
        }
    }
}

@@ -546,16 +546,53 @@
 taType;%0A
+import org.yamcs.utils.TimeEncoding;%0A
 import o
@@ -2730,16 +2730,116 @@
 ndId())%0A
+                .setGenerationTimeUTC(TimeEncoding.toString(pc.getCommandId().getGenerationTime()))%0A
         
@@ -2877,16 +2877,33 @@
 butes())
+%0A                
 .build()
@@ -3146,24 +3146,41 @@
 newBuilder()
+%0A                
 .setName(key
@@ -3233,16 +3233,33 @@
 (value))
+%0A                
 .build()
@@ -3332,41 +3332,180 @@
 er()
-.setCommandId(cmdId).addAttr(cha)
+%0A                .setGenerationTimeUTC(TimeEncoding.toString(cmdId.getGenerationTime()))%0A                .setCommandId(cmdId)%0A                .addAttr(cha)%0A                
 .bui

Add UTC-string gentime to websocket cmdhist