Linter fixes
[e-mobility-charging-stations-simulator.git] / src / charging-station / UIServiceWorkerBroadcastChannel.ts
index d50d514a469496159b5aad15f752bde3c3a0d031..cdbe108df333e9f6b6388f91e5327be60a8a3821 100644 (file)
-import { BroadcastChannelResponse, MessageEvent } from '../types/WorkerBroadcastChannel';
-import logger from '../utils/Logger';
 import type AbstractUIService from './ui-server/ui-services/AbstractUIService';
 import WorkerBroadcastChannel from './WorkerBroadcastChannel';
+import { type ResponsePayload, ResponseStatus } from '../types/UIProtocol';
+import type {
+  BroadcastChannelResponse,
+  BroadcastChannelResponsePayload,
+  MessageEvent,
+} from '../types/WorkerBroadcastChannel';
+import logger from '../utils/Logger';
 
 const moduleName = 'UIServiceWorkerBroadcastChannel';
 
+type Responses = {
+  responsesExpected: number;
+  responsesReceived: number;
+  responses: BroadcastChannelResponsePayload[];
+};
+
 export default class UIServiceWorkerBroadcastChannel extends WorkerBroadcastChannel {
-  private uiService: AbstractUIService;
+  private readonly uiService: AbstractUIService;
+  private readonly responses: Map<string, Responses>;
 
   constructor(uiService: AbstractUIService) {
     super();
     this.uiService = uiService;
     this.onmessage = this.responseHandler.bind(this) as (message: MessageEvent) => void;
     this.onmessageerror = this.messageErrorHandler.bind(this) as (message: MessageEvent) => void;
+    this.responses = new Map<string, Responses>();
   }
 
   private responseHandler(messageEvent: MessageEvent): void {
-    if (this.isRequest(messageEvent.data)) {
+    const validatedMessageEvent = this.validateMessageEvent(messageEvent);
+    if (validatedMessageEvent === false) {
+      return;
+    }
+    if (this.isRequest(validatedMessageEvent.data) === true) {
       return;
     }
-    const [uuid, responsePayload] = messageEvent.data as BroadcastChannelResponse;
+    const [uuid, responsePayload] = validatedMessageEvent.data as BroadcastChannelResponse;
+    if (this.responses.has(uuid) === false) {
+      this.responses.set(uuid, {
+        responsesExpected: this.uiService.getBroadcastChannelExpectedResponses(uuid),
+        responsesReceived: 1,
+        responses: [responsePayload],
+      });
+    } else if (
+      this.responses.get(uuid)?.responsesReceived <= this.responses.get(uuid)?.responsesExpected
+    ) {
+      this.responses.get(uuid).responsesReceived++;
+      this.responses.get(uuid).responses.push(responsePayload);
+    }
+    if (
+      this.responses.get(uuid)?.responsesReceived === this.responses.get(uuid)?.responsesExpected
+    ) {
+      this.uiService.sendResponse(uuid, this.buildResponsePayload(uuid));
+      this.responses.delete(uuid);
+      this.uiService.deleteBroadcastChannelRequest(uuid);
+    }
+  }
 
-    this.uiService.sendResponse(uuid, responsePayload);
+  private buildResponsePayload(uuid: string): ResponsePayload {
+    const responsesStatus =
+      this.responses
+        .get(uuid)
+        ?.responses.every(({ status }) => status === ResponseStatus.SUCCESS) === true
+        ? ResponseStatus.SUCCESS
+        : ResponseStatus.FAILURE;
+    return {
+      status: responsesStatus,
+      hashIdsSucceeded: this.responses
+        .get(uuid)
+        ?.responses.map(({ status, hashId }) => {
+          if (status === ResponseStatus.SUCCESS) {
+            return hashId;
+          }
+        })
+        .filter((hashId) => hashId !== undefined),
+      ...(responsesStatus === ResponseStatus.FAILURE && {
+        hashIdsFailed: this.responses
+          .get(uuid)
+          ?.responses.map(({ status, hashId }) => {
+            if (status === ResponseStatus.FAILURE) {
+              return hashId;
+            }
+          })
+          .filter((hashId) => hashId !== undefined),
+      }),
+      ...(responsesStatus === ResponseStatus.FAILURE && {
+        responsesFailed: this.responses
+          .get(uuid)
+          ?.responses.map((response) => {
+            if (response.status === ResponseStatus.FAILURE) {
+              return response;
+            }
+          })
+          .filter((response) => response !== undefined),
+      }),
+    };
   }
 
   private messageErrorHandler(messageEvent: MessageEvent): void {
     logger.error(
       `${this.uiService.logPrefix(moduleName, 'messageErrorHandler')} Error at handling message:`,
-      { messageEvent, messageEventData: messageEvent.data }
+      messageEvent
     );
   }
 }