From b290415baa637e10d8d6d3b79c81116391e7523a Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Fri, 22 Jul 2022 13:22:34 +0100
Subject: [PATCH] Add ConnectionRegisterListener functor

---
 Sources/ElixxirDAppsSDK/Connection.swift      |  4 +
 .../ConnectionRegisterListener.swift          | 39 ++++++++++
 .../{Legacy => }/Message.swift                |  8 ++
 .../{Legacy => }/MessageListener.swift        | 78 ++++++++++++-------
 4 files changed, 102 insertions(+), 27 deletions(-)
 create mode 100644 Sources/ElixxirDAppsSDK/ConnectionRegisterListener.swift
 rename Sources/ElixxirDAppsSDK/{Legacy => }/Message.swift (85%)
 rename Sources/ElixxirDAppsSDK/{Legacy => }/MessageListener.swift (53%)

diff --git a/Sources/ElixxirDAppsSDK/Connection.swift b/Sources/ElixxirDAppsSDK/Connection.swift
index 04d10312..0ae7cf32 100644
--- a/Sources/ElixxirDAppsSDK/Connection.swift
+++ b/Sources/ElixxirDAppsSDK/Connection.swift
@@ -4,6 +4,7 @@ public struct Connection {
   public var isAuthenticated: ConnectionIsAuthenticated
   public var getId: ConnectionGetId
   public var getPartner: ConnectionGetPartner
+  public var registerListener: ConnectionRegisterListener
   public var send: ConnectionSend
   public var close: ConnectionClose
 }
@@ -14,6 +15,7 @@ extension Connection {
       isAuthenticated: .live(bindingsConnection),
       getId: .live(bindingsConnection),
       getPartner: .live(bindingsConnection),
+      registerListener: .live(bindingsConnection),
       send: .live(bindingsConnection),
       close: .live(bindingsConnection)
     )
@@ -24,6 +26,7 @@ extension Connection {
       isAuthenticated: .live(bindingsConnection),
       getId: .live(bindingsConnection),
       getPartner: .live(bindingsConnection),
+      registerListener: .live(bindingsConnection),
       send: .live(bindingsConnection),
       close: .live(bindingsConnection)
     )
@@ -35,6 +38,7 @@ extension Connection {
     isAuthenticated: .unimplemented,
     getId: .unimplemented,
     getPartner: .unimplemented,
+    registerListener: .unimplemented,
     send: .unimplemented,
     close: .unimplemented
   )
diff --git a/Sources/ElixxirDAppsSDK/ConnectionRegisterListener.swift b/Sources/ElixxirDAppsSDK/ConnectionRegisterListener.swift
new file mode 100644
index 00000000..b9218674
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ConnectionRegisterListener.swift
@@ -0,0 +1,39 @@
+import Bindings
+import XCTestDynamicOverlay
+
+public struct ConnectionRegisterListener {
+  public var run: (Int, MessageListener) throws -> Void
+
+  public func callAsFunction(
+    messageType: Int,
+    listener: MessageListener
+  ) throws {
+    try run(messageType, listener)
+  }
+}
+
+extension ConnectionRegisterListener {
+  public static func live(_ bindingsConnection: BindingsConnection) -> ConnectionRegisterListener {
+    ConnectionRegisterListener { messageType, listener in
+      try bindingsConnection.registerListener(
+        messageType,
+        newListener: listener.makeBindingsListener()
+      )
+    }
+  }
+
+  public static func live(_ bindingsConnection: BindingsAuthenticatedConnection) -> ConnectionRegisterListener {
+    ConnectionRegisterListener { messageType, listener in
+      try bindingsConnection.registerListener(
+        messageType,
+        newListener: listener.makeBindingsListener()
+      )
+    }
+  }
+}
+
+extension ConnectionRegisterListener {
+  public static let unimplemented = ConnectionRegisterListener(
+    run: XCTUnimplemented("\(Self.self)")
+  )
+}
diff --git a/Sources/ElixxirDAppsSDK/Legacy/Message.swift b/Sources/ElixxirDAppsSDK/Message.swift
similarity index 85%
rename from Sources/ElixxirDAppsSDK/Legacy/Message.swift
rename to Sources/ElixxirDAppsSDK/Message.swift
index b6fc6c4c..b2c13b7d 100644
--- a/Sources/ElixxirDAppsSDK/Legacy/Message.swift
+++ b/Sources/ElixxirDAppsSDK/Message.swift
@@ -46,4 +46,12 @@ extension Message: Codable {
     case encrypted = "Encrypted"
     case roundId = "RoundId"
   }
+
+  static func decode(_ data: Data) throws -> Message {
+    try JSONDecoder().decode(Self.self, from: data)
+  }
+
+  func encode() throws -> Data {
+    try JSONEncoder().encode(self)
+  }
 }
diff --git a/Sources/ElixxirDAppsSDK/Legacy/MessageListener.swift b/Sources/ElixxirDAppsSDK/MessageListener.swift
similarity index 53%
rename from Sources/ElixxirDAppsSDK/Legacy/MessageListener.swift
rename to Sources/ElixxirDAppsSDK/MessageListener.swift
index f36171dc..a95b1018 100644
--- a/Sources/ElixxirDAppsSDK/Legacy/MessageListener.swift
+++ b/Sources/ElixxirDAppsSDK/MessageListener.swift
@@ -1,4 +1,54 @@
-//import Bindings
+import Bindings
+import XCTestDynamicOverlay
+
+public struct MessageListener {
+  public init(
+    name: String = "MessageListener",
+    handle: @escaping (Message) -> Void
+  ) {
+    self.name = name
+    self.handle = handle
+  }
+
+  public var name: String
+  public var handle: (Message) -> Void
+}
+
+extension MessageListener {
+  public static let unimplemented = MessageListener(
+    handle: XCTUnimplemented("\(Self.self)")
+  )
+}
+
+extension MessageListener {
+  func makeBindingsListener() -> BindingsListenerProtocol {
+    class Listener: NSObject, BindingsListenerProtocol {
+      init(_ listener: MessageListener) {
+        self.listener = listener
+      }
+
+      let listener: MessageListener
+
+      func hear(_ item: Data?) {
+        guard let item = item else {
+          fatalError("BindingsListener.hear received `nil`")
+        }
+        do {
+          listener.handle(try Message.decode(item))
+        } catch {
+          fatalError("BindingsListener.hear message decoding failed with error: \(error)")
+        }
+      }
+
+      func name() -> String {
+        listener.name
+      }
+    }
+
+    return Listener(self)
+  }
+}
+
 //
 //public struct MessageListener {
 //  public var listen: (Int, String, @escaping (Message) -> Void) -> Void
@@ -38,32 +88,6 @@
 //  }
 //}
 //
-//private class Listener: NSObject, BindingsListenerProtocol {
-//  init(listenerName: String, onHear: @escaping (Message) -> Void) {
-//    self.listenerName = listenerName
-//    self.onHear = onHear
-//    super.init()
-//  }
-//
-//  let listenerName: String
-//  let onHear: (Message) -> Void
-//  let decoder = JSONDecoder()
-//
-//  func hear(_ item: Data?) {
-//    guard let item = item else {
-//      fatalError("BindingsListenerProtocol.hear received `nil`")
-//    }
-//    do {
-//      onHear(try decoder.decode(Message.self, from: item))
-//    } catch {
-//      fatalError("Message decoding failed with error: \(error)")
-//    }
-//  }
-//
-//  func name() -> String {
-//    listenerName
-//  }
-//}
 //
 //#if DEBUG
 //extension MessageListener {
-- 
GitLab