1package otr3
2
3import "fmt"
4
5// MessageEvent define the events used to indicate the messages that need to be sent
6type MessageEvent int
7
8const (
9	// MessageEventEncryptionRequired is signaled when our policy requires encryption but we are trying to send an unencrypted message.
10	MessageEventEncryptionRequired MessageEvent = iota
11
12	// MessageEventEncryptionError is signaled when an error occured while encrypting a message and the message was not sent.
13	MessageEventEncryptionError
14
15	// MessageEventConnectionEnded is signaled when we are asked to send a message but the peer has ended the private conversation.
16	// At this point the connection should be closed or refreshed.
17	MessageEventConnectionEnded
18
19	// MessageEventSetupError will be signaled when a private conversation could not be established. The reason for this will be communicated with the attached error instance.
20	MessageEventSetupError
21
22	// MessageEventMessageReflected will be signaled if we received our own OTR messages.
23	MessageEventMessageReflected
24
25	// MessageEventMessageSent is signaled when a message is sent after having been queued
26	MessageEventMessageSent
27
28	// MessageEventMessageResent is signaled when a message is resent
29	MessageEventMessageResent
30
31	// MessageEventReceivedMessageNotInPrivate will be signaled when we receive an encrypted message that we cannot read, because we don't have an established private connection
32	MessageEventReceivedMessageNotInPrivate
33
34	// MessageEventReceivedMessageUnreadable will be signaled when we cannot read the received message.
35	MessageEventReceivedMessageUnreadable
36
37	// MessageEventReceivedMessageMalformed is signaled when we receive a message that contains malformed data.
38	MessageEventReceivedMessageMalformed
39
40	// MessageEventLogHeartbeatReceived is triggered when we received a heartbeat.
41	MessageEventLogHeartbeatReceived
42
43	// MessageEventLogHeartbeatSent is triggered when we have sent a heartbeat.
44	MessageEventLogHeartbeatSent
45
46	// MessageEventReceivedMessageGeneralError will be signaled when we receive an OTR error from the peer.
47	// The message parameter will be passed, containing the error message
48	MessageEventReceivedMessageGeneralError
49
50	// MessageEventReceivedMessageUnencrypted is triggered when we receive a message that was sent in the clear when it should have been encrypted.
51	// The actual message received will also be passed.
52	MessageEventReceivedMessageUnencrypted
53
54	// MessageEventReceivedMessageUnrecognized is triggered when we receive an OTR message whose type we cannot recognize
55	MessageEventReceivedMessageUnrecognized
56
57	// MessageEventReceivedMessageForOtherInstance is triggered when we receive and discard a message for another instance
58	MessageEventReceivedMessageForOtherInstance
59)
60
61// MessageEventHandler handles MessageEvents
62type MessageEventHandler interface {
63	// HandleMessageEvent should handle and send the appropriate message(s) to the sender/recipient depending on the message events
64	HandleMessageEvent(event MessageEvent, message []byte, err error, trace ...interface{})
65}
66
67type dynamicMessageEventHandler struct {
68	eh func(event MessageEvent, message []byte, err error, trace ...interface{})
69}
70
71func (d dynamicMessageEventHandler) HandleMessageEvent(event MessageEvent, message []byte, err error, trace ...interface{}) {
72	d.eh(event, message, err, trace...)
73}
74
75func (c *Conversation) messageEvent(e MessageEvent, trace ...interface{}) {
76	if c.messageEventHandler != nil {
77		c.messageEventHandler.HandleMessageEvent(e, nil, nil, trace...)
78	}
79}
80
81func (c *Conversation) messageEventWithError(e MessageEvent, err error) {
82	if c.messageEventHandler != nil {
83		c.messageEventHandler.HandleMessageEvent(e, nil, err)
84	}
85}
86
87func (c *Conversation) messageEventWithMessage(e MessageEvent, msg []byte) {
88	if c.messageEventHandler != nil {
89		c.messageEventHandler.HandleMessageEvent(e, msg, nil)
90	}
91}
92
93// String returns the string representation of the MessageEvent
94func (s MessageEvent) String() string {
95	switch s {
96	case MessageEventEncryptionRequired:
97		return "MessageEventEncryptionRequired"
98	case MessageEventEncryptionError:
99		return "MessageEventEncryptionError"
100	case MessageEventConnectionEnded:
101		return "MessageEventConnectionEnded"
102	case MessageEventSetupError:
103		return "MessageEventSetupError"
104	case MessageEventMessageReflected:
105		return "MessageEventMessageReflected"
106	case MessageEventMessageSent:
107		return "MessageEventMessageSent"
108	case MessageEventMessageResent:
109		return "MessageEventMessageResent"
110	case MessageEventReceivedMessageNotInPrivate:
111		return "MessageEventReceivedMessageNotInPrivate"
112	case MessageEventReceivedMessageUnreadable:
113		return "MessageEventReceivedMessageUnreadable"
114	case MessageEventReceivedMessageMalformed:
115		return "MessageEventReceivedMessageMalformed"
116	case MessageEventLogHeartbeatReceived:
117		return "MessageEventLogHeartbeatReceived"
118	case MessageEventLogHeartbeatSent:
119		return "MessageEventLogHeartbeatSent"
120	case MessageEventReceivedMessageGeneralError:
121		return "MessageEventReceivedMessageGeneralError"
122	case MessageEventReceivedMessageUnencrypted:
123		return "MessageEventReceivedMessageUnencrypted"
124	case MessageEventReceivedMessageUnrecognized:
125		return "MessageEventReceivedMessageUnrecognized"
126	case MessageEventReceivedMessageForOtherInstance:
127		return "MessageEventReceivedMessageForOtherInstance"
128	default:
129		return "MESSAGE EVENT: (THIS SHOULD NEVER HAPPEN)"
130	}
131}
132
133type combinedMessageEventHandler struct {
134	handlers []MessageEventHandler
135}
136
137func (c combinedMessageEventHandler) HandleMessageEvent(event MessageEvent, message []byte, err error, trace ...interface{}) {
138	for _, h := range c.handlers {
139		if h != nil {
140			h.HandleMessageEvent(event, message, err, trace...)
141		}
142	}
143}
144
145// CombineMessageEventHandlers creates a MessageEventHandler that will call all handlers
146// given to this function. It ignores nil entries.
147func CombineMessageEventHandlers(handlers ...MessageEventHandler) MessageEventHandler {
148	return combinedMessageEventHandler{handlers}
149}
150
151// DebugMessageEventHandler is a MessageEventHandler that dumps all MessageEvents to standard error
152type DebugMessageEventHandler struct{}
153
154// HandleMessageEvent dumps all message events
155func (DebugMessageEventHandler) HandleMessageEvent(event MessageEvent, message []byte, err error, trace ...interface{}) {
156	fmt.Fprintf(standardErrorOutput, "%sHandleMessageEvent(%s, message: %#v, error: %v, trace: %v)\n", debugPrefix, event, string(message), err, trace)
157}
158