module arch.node.engines.pub_sub_topic_messages;

import arch.node.engines.net_registry_messages open;
import arch.node.types.storage open;

import arch.node.types.basics open;
import arch.node.types.crypto open;
import arch.node.types.identities open;
import arch.node.types.messages open;

syntax alias TopicMsgID := Digest;

type TopicMsg :=
  mkTopicMsg@{
    publisher : PublisherID;
    seq : Nat;
    deps : List TopicMsgID;
    seen : List TopicMsgID;
    content : TopicMsgContent;
    sig : Commitment;
  };

type TopicMsgContent :=
  | TopicMsgContentMsg ByteString
  | TopicMsgContentChunk (Pair ByteString Chunk)
  | TopicMsgContentChunkRef (Pair ByteString ChunkCommitment)
  | TopicMsgContentAck TopicMsgAck;

type TopicMsgAck :=
  mkTopicMsgAck@{
    expiry : AbsTime;
  };

type TopicSubRequest :=
  mkTopicSubRequest@{
    topic : TopicID;
  };

type TopicSubReplyOk := | TopicSubReplyOkSuccess;

type TopicSubReplyError := | TopicSubReplyErrorDenied;

TopicSubReply : Type := Result TopicSubReplyOk TopicSubReplyError;

type TopicUnsubRequest :=
  mkTopicUnsubRequest@{
    topic : TopicID;
  };

type TopicUnsubReplyOk := | TopicUnsubReplyOkSuccess;

type TopicUnsubReplyError := | TopicUnsubReplyErrorNotSubscribed;

TopicUnsubReply : Type := Result TopicUnsubReplyOk TopicUnsubReplyError;

type PubSubTopicMsg :=
  | PubSubTopicMsgForward TopicMsg
  | PubSubTopicMsgSubRequest TopicSubRequest
  | PubSubTopicMsgSubReply TopicSubReply
  | PubSubTopicMsgUnsubRequest TopicUnsubRequest
  | PubSubTopicMsgUnsubReply TopicUnsubReply;