'use strict';

// This script depends on the following scripts:
//    /file-system-access/resources/messaging-helpers.js
//    /file-system-access/resources/test-helpers.js

// add_message_event_handlers() is the helper function used to setup all
// message targets, including iframes and workers.
//
// Adds a message event handler and a message error handler to |receiver|.
// The 'data' property from received MessageEvents must include a 'type'
// property. The 'type' selects the test logic to run. Most message type
// handlers use postMessage() to respond to the sender with test results.
// The sender then validates the test results after receiving the response.
//
// Both |target| and |target_origin| are optional. |target| is used
// to send message responses back to the sender. When omitted, the
// 'source' from received MessageEvents is used instead.
//
// For window messaging, |target_origin| specifies the origin to receive
// responses. Most window tests use '*' for the |target_origin|. Worker
// and message port tests must use undefined for |target_origin| to avoid
// exceptions.
function add_message_event_handlers(receiver, target, target_origin) {
  receiver.addEventListener('message', async function (message_event) {
    const message_data = message_event.data;

    // Reply to the sender using the 'source' from the received MessageEvent.
    let message_source = message_event.source;
    if (message_source === null) {
      // However, some message senders, like DedicatedWorkers, don't include
      // a source. Fallback to the target when the source is null.
      message_source = target;
    }

    try {
      switch (message_data.type) {
        case 'receive-message-port':
          // Receive a MessagePort to use as a message target for testing.
          add_message_event_handlers(
            /*receiver=*/message_data.message_port,
            /*target=*/message_data.message_port);
          message_data.message_port.start();
          break;

        case 'create-broadcast-channel':
          // Create a BroadcastChannel to use as a message target for testing.
          const broadcast_channel =
            new BroadcastChannel(message_data.broadcast_channel_name);
          add_message_event_handlers(
            /*receiver=*/broadcast_channel,
            /*target=*/broadcast_channel);
          message_source.postMessage(
            { type: 'broadcast-channel-created' },
            { targetOrigin: target_origin });
          break;

        case 'receive-file-system-handles':
          // Receive a list of cloned FileSystemFileHandles. Access the
          // properties of each FileSystemFileHandle by serializing the
          // handle to a JavaScript object. Then respond with the serialized
          // results, enabling the sender to verify that the cloned handle
          // produced the expected property values from this execution context.
          const serialized_handles = [];
          const cloned_handles = message_data.cloned_handles;
          for (let i = 0; i < cloned_handles.length; ++i) {
            const serialized = await serialize_handle(cloned_handles[i]);
            serialized_handles.push(serialized);
          }
          message_source.postMessage({
            type: 'receive-serialized-file-system-handles',
            serialized_handles,
            // Respond with the cloned handles to create new clones for
            // the sender to verify.
            cloned_handles,
          }, { targetOrigin: target_origin });
          break;

        case 'receive-serialized-file-system-handles':
          // Do nothing. This message is meant for test runner validation.
          // Other message targets may receive this message while testing
          // broadcast channels.
          break;

        case 'create-file':
          // Create a new file and then respond to the sender with it.
          const directory = await navigator.storage.getDirectory();
          const file_handle =
            await directory.getFileHandle('temp-file', { create: true });
          message_source.postMessage(
            { type: 'receive-file', file_handle },
            { targetOrigin: target_origin });
          break;

        case 'create-directory':
          // Create a new directory and then respond to the sender with it.
          const parent_directory = await navigator.storage.getDirectory();
          const directory_handle =
            await parent_directory.getDirectoryHandle('temp-directory',
              { create: true });
          message_source.postMessage(
            { type: 'receive-directory', directory_handle },
            { targetOrigin: target_origin });
          break;

        case 'create-sync-access-handle':
          // Receive a file and create a sync access handle out of it. Report
          // success to the sender.
          let success = true;
          try {
            const access_handle = await message_data.file_handle.createSyncAccessHandle();
            await access_handle.close();
          } catch (error) {
            success = false;
          }

          message_source.postMessage(
            { type: 'receive-sync-access-handle-result', success },
            { targetOrigin: target_origin });
          break;

        default:
          throw `Unknown message type: '${message_data.type}'`;
      }
    } catch (error) {
      // Respond with an error to trigger a failure in the sender's
      // test runner.
      message_source.postMessage(`ERROR: ${error}`,
        { targetOrigin: target_origin });
    }
  });

  receiver.addEventListener('messageerror', async function (message_event) {
    // Select the target for message responses (see comment in 'message' event
    // listener above).
    let message_source = message_event.source;
    if (message_source === null) {
      message_source = target;
    }

    try {
      // Respond with the MessageEvent's property values, enabling the sender
      // to verify results.
      const serialized_message_error_event =
        serialize_message_error_event(message_event);
      message_source.postMessage({
        type: 'serialized-message-error',
        serialized_message_error_event
      }, { targetOrigin: target_origin });
    } catch (error) {
      // Respond with an error to trigger a failure in the sender's
      // test runner.
      message_source.postMessage(`ERROR: ${error}`,
        { targetOrigin: target_origin });
    }
  });
}
