<!DOCTYPE html>
<meta charset="utf-8">
<title>Sending a message through PresentationConnection</title>
<link rel="author" title="Tomoyuki Shimizu" href="https://github.com/tomoyukilabs/">
<link rel="help" href="http://w3c.github.io/presentation-api/#sending-a-message-through-presentationconnection">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="common.js"></script>
<script src="support/stash.js"></script>

<p>Click the button below and select the available presentation display, to start the manual test.</p>
<button id="presentBtn">Start Presentation Test</button>

<script>
  setup({explicit_timeout: true});

  const message1 = '1st';
  const message2 = '2nd';
  const message3 = new Uint8Array([51, 114, 100]);      // "3rd"
  const message4 = new Uint8Array([52, 116, 104]);      // "4th"
  const message5 = new Uint8Array([108, 97, 115, 116]); // "last"

  const toUint8Array = buf => {
    return buf instanceof ArrayBuffer ? new Uint8Array(buf) : buf;
  }

  // compare two ArrayBuffer or Uint8Array
  const compare = (a, b) => {
    const p = toUint8Array(a);
    const q = toUint8Array(b);
    return !!p && !!q && p.every((item, index) => { return item === q[index]; });
  };

  let connection;

  const presentBtn = document.getElementById('presentBtn');
  presentBtn.onclick = () => {
    presentBtn.disabled = true;
    const stash = new Stash(stashIds.toController, stashIds.toReceiver);
    const request = new PresentationRequest('support/PresentationConnection_send_receiving-ua.html');

    let eventWatcher;

    promise_test(t => {
      t.add_cleanup(() => {
        connection.onconnect = () => { connection.terminate(); };
        if (connection.state === 'closed')
          request.reconnect(connection.id);
        else
          connection.terminate();
      });

      return request.start().then(c => {
        // enable timeout again, cause no user action is needed from here.
        t.step_timeout(() => {
          t.force_timeout();
          t.done();
        }, 3000);

        connection = c;
        eventWatcher = new EventWatcher(t, connection, 'connect');
        return eventWatcher.wait_for('connect');
      }).then(() => {
        return stash.init();
      }).then(() => {
        stash.send({ type: 'ok' });
        eventWatcher = new EventWatcher(t, connection, 'message');
        return eventWatcher.wait_for('message');
      }).then(evt => {
        assert_true(typeof evt.data === 'string' && evt.data === message1, 'send a string correctly');
        return eventWatcher.wait_for('message');
      }).then(evt => {
        assert_true(typeof evt.data === 'string' && evt.data === message2, 'send a string correctly');
        return eventWatcher.wait_for('message');
      }).then(evt => {
        assert_true(evt.data instanceof ArrayBuffer && compare(evt.data, message3), 'send a Blob correctly');
        return eventWatcher.wait_for('message');
      }).then(evt => {
        assert_true(evt.data instanceof ArrayBuffer && compare(evt.data, message4), 'send an ArrayBuffer correctly');
        return eventWatcher.wait_for('message');
      }).then(evt => {
        assert_true(evt.data instanceof ArrayBuffer && compare(evt.data, message5), 'send an ArrayBufferView correctly');
        return stash.send({ type: 'ok' });
      }).then(() => {
        return stash.receive();
      }).then(data => {
        const result = JSON.parse(data);
        if (!result.type || result.type !== 'error')
          assert_unreached('an InvalidStateError is thrown if the state is "closed"');
        else
          assert_throws_dom('InvalidStateError', () => {
            throw new DOMException(result.message, result.name);
          }, 'an InvalidStateError is thrown if the state is "closed"');
      });
    });
  };
</script>
