feat(bulk-move): retrieve forum configuration from startup data

This commit changes the mock data by real forum configuration, so the
modal shows the actual list of forums, etc.

The startup data contains the forum configuration for the Community
Console's UI language, but configurations for other languages are
missing. Thus, only one language is shown in the modal.

A follow-up commit will add support for other languages.

Bug: twpowertools:51
Change-Id: I6a6a6964762249684a6fa1a2fcdea35209dbfa83
diff --git a/src/entryPoints/communityConsole/contentScripts/main.ts b/src/entryPoints/communityConsole/contentScripts/main.ts
index 16e3274..4e17e0a 100644
--- a/src/entryPoints/communityConsole/contentScripts/main.ts
+++ b/src/entryPoints/communityConsole/contentScripts/main.ts
@@ -133,6 +133,7 @@
                 optionsProvider,
                 new BulkMoveButtonInjectorAdapter(
                   ccThreadListGenericActionButtonInjector,
+                  startupDataStorage,
                 ),
               ),
             ],
diff --git a/src/features/bulkMove/infrastructure/ui/injectors/bulkMoveButton.injector.adapter.ts b/src/features/bulkMove/infrastructure/ui/injectors/bulkMoveButton.injector.adapter.ts
index 1e1b9da..808a9fc 100644
--- a/src/features/bulkMove/infrastructure/ui/injectors/bulkMoveButton.injector.adapter.ts
+++ b/src/features/bulkMove/infrastructure/ui/injectors/bulkMoveButton.injector.adapter.ts
@@ -1,7 +1,9 @@
+import { StartupDataStoragePort } from '../../../../../services/communityConsole/StartupDataStorage.port';
 import { ThreadListGenericActionButtonInjectorPort } from '../../../../../ui/injectors/threadListGenericActionButton.injector.port';
 import { Forum } from '../../../../../domain/forum';
 import BulkMoveModal from '../../../ui/components/BulkMoveModal';
 import { BulkMoveButtonInjectorPort } from '../../../ui/injectors/bulkMoveButton.injector.port';
+import { ForumsFactory } from './forums.factory';
 
 const BULK_MOVE_ACTION_KEY = 'bulk-move';
 
@@ -10,8 +12,11 @@
 {
   private modal: BulkMoveModal | undefined;
 
+  private readonly forumsFactory = new ForumsFactory();
+
   constructor(
     private readonly buttonInjector: ThreadListGenericActionButtonInjectorPort,
+    private readonly startupDataStorage: StartupDataStoragePort,
   ) {}
 
   execute() {
@@ -50,76 +55,23 @@
   }
 
   private getForums(): Forum[] {
-    return [
-      {
-        name: 'Google Chrome',
-        id: 'chrome-dummy',
-        languageConfigurations: [
-          {
-            id: 'es',
-            name: 'Español',
-            categories: [
-              { id: 'learn', name: 'Aprende sobre Chrome' },
-              { id: 'bug', name: 'Reporta un bug sobre Chrome' },
-            ],
-            details: [
-              {
-                id: 'os',
-                name: 'Sistema operativo',
-                options: [
-                  { id: 'win', name: 'Windows' },
-                  { id: 'mac', name: 'Mac' },
-                  { id: 'linux', name: 'Linux' },
-                ],
-              },
-              {
-                id: 'channel',
-                name: 'Canal de Chrome',
-                options: [
-                  { id: 'stable', name: 'Estable' },
-                  { id: 'beta', name: 'Beta' },
-                  { id: 'dev', name: 'Dev' },
-                  { id: 'canary', name: 'Canary' },
-                ],
-              },
-            ],
-          },
-          {
-            id: 'en',
-            name: 'English',
-            categories: [],
-            details: [],
-          },
-          {
-            id: 'ca',
-            name: 'Català',
-            categories: [
-              { id: 'learn', name: 'Aprèn sobre Chrome' },
-              { id: 'bug', name: 'Reporta un bug de Chrome' },
-              { id: 'fun', name: 'Yay!' },
-            ],
-            details: [],
-          },
-        ],
-      },
-      {
-        name: 'Google AI',
-        id: 'ai-dummy',
-        languageConfigurations: [
-          {
-            id: 'es',
-            name: 'Castellano',
-            categories: [],
-            details: [],
-          },
-          {
-            id: 'ca',
-            name: 'Català',
-            categories: [],
-            details: [],
-          },
-        ],
-      },
-    ];
+    const startupData = this.startupDataStorage.get();
+    const forumsInfo = startupData.getRawForumsInfo();
+    const publicForumsInfo = this.getPublicForums(forumsInfo);
+    const displayLanguage = startupData.getDisplayLanguage();
+    return this.forumsFactory.convertProtobufListToEntities(
+      publicForumsInfo,
+      displayLanguage,
+    );
+  }
+
+  private getPublicForums(forums: any) {
+    return forums.filter((forumInfo: any) => {
+      const forumVisibility = forumInfo?.[2]?.[18];
+      const VISIBILITY_PUBLIC = 1;
+      // Don't include non-public forums in the list of forums to choose
+      // from.
+      return forumVisibility == VISIBILITY_PUBLIC;
+    });
   }
 }
diff --git a/src/features/bulkMove/infrastructure/ui/injectors/forums.factory.ts b/src/features/bulkMove/infrastructure/ui/injectors/forums.factory.ts
new file mode 100644
index 0000000..7bd7584
--- /dev/null
+++ b/src/features/bulkMove/infrastructure/ui/injectors/forums.factory.ts
@@ -0,0 +1,72 @@
+import { Forum } from '../../../../../domain/forum';
+
+export class ForumsFactory {
+  convertProtobufListToEntities(forums: any, displayLanguage: string): Forum[] {
+    return forums.map((rawForumInfo: any) =>
+      this.convertProtobufToEntity(rawForumInfo, displayLanguage),
+    );
+  }
+
+  convertProtobufToEntity(forumInfo: any, displayLanguage: string) {
+    const productForum = forumInfo[2];
+    const languageConfigurations = productForum?.[10];
+    const defaultLanguageConfiguration = this.getDefaultLanguageConfiguration(
+      languageConfigurations,
+      displayLanguage,
+    );
+
+    return {
+      name: defaultLanguageConfiguration?.[4] ?? 'Unknown forum name',
+      id: productForum?.[1]?.[1],
+      languageConfigurations:
+        languageConfigurations?.map?.((configuration: any) =>
+          this.convertLanguageConfiguration(configuration),
+        ) ?? [],
+    };
+  }
+
+  private getDefaultLanguageConfiguration(
+    languageConfigurations: any,
+    displayLanguage: string,
+  ) {
+    return (
+      languageConfigurations?.find?.(
+        (configuration: any) => configuration[1] === displayLanguage,
+      ) ?? languageConfigurations?.[0]
+    );
+  }
+
+  private convertLanguageConfiguration(configuration: any) {
+    return {
+      id: configuration?.[1],
+      name: configuration?.[1], // TODO: Change with localized language name
+      categories: configuration?.[12]?.map?.((category: any) =>
+        this.convertCategory(category),
+      ),
+      details:
+        configuration?.[13]?.map?.((detail: any) =>
+          this.convertDetail(detail),
+        ) ?? [],
+    };
+  }
+
+  private convertCategory(category: any) {
+    return {
+      id: category?.[1],
+      name: category?.[2],
+    };
+  }
+
+  private convertDetail(detail: any) {
+    return {
+      id: detail?.[1],
+      name: detail?.[2],
+      options: detail?.[3]?.map?.((option: any) => {
+        return {
+          id: option?.[1],
+          name: option?.[2],
+        };
+      }),
+    };
+  }
+}
diff --git a/src/models/StartupData.js b/src/models/StartupData.js
index 047c154..328bf5c 100644
--- a/src/models/StartupData.js
+++ b/src/models/StartupData.js
@@ -38,4 +38,8 @@
   getCurrentUserModel() {
     return new UserModel(this.getRawUser(), this);
   }
+
+  getDisplayLanguage() {
+    return this.data[1]?.[1]?.[3]?.[6] ?? 'en';
+  }
 }