<!doctype html>
<meta charset=utf-8>
<title>RTCSctpTransport.prototype.maxMessageSize</title>
<link rel="help" href="https://w3c.github.io/webrtc-pc/#rtcsctptransport-interface">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
'use strict';

// This test has an assert_unreached() that requires that the variable
// canSendSize (initiated below) is greater than 2, if non-zero. The reason
// is that we need two non-zero values that are less that that value for
// testing with predictable results. This is a bit unfortunate but shouldn't
// have any practical impact.

// Helper class to read SDP attributes and generate SDPs with modified attribute values
class SDPAttributeHelper {
  constructor(attrName, valueRegExpStr) {
    this.attrName = attrName;
    this.re = new RegExp(`^a=${attrName}:(${valueRegExpStr})\\r\\n`, 'm');
  }

  getValue(sdp) {
    const matches = sdp.match(this.re);
    return matches ? matches[1] : null;
  }

  sdpWithValue(sdp, value) {
    const matches = sdp.match(this.re);
    const sdpParts = sdp.split(matches[0]);
    const attributeLine = arguments.length > 1 ? `a=${this.attrName}:${value}\r\n` : '';
    return `${sdpParts[0]}${attributeLine}${sdpParts[1]}`;
  }

  sdpWithoutAttribute(sdp) {
    return this.sdpWithValue(sdp);
  }
}

const mmsAttributeHelper = new SDPAttributeHelper('max-message-size', '\\d+');
let canSendSize;
const remoteValue1 = 1;
const remoteValue2 = 2;

promise_test(t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  assert_equals(pc.sctp, null);
  let maxMessageSize;

  return generateDataChannelOffer(pc)
  .then((offer) => {
    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
      'SDP should have max-message-size attribute');

    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0) };
    return pc.setRemoteDescription(offer);
  })
  .then(() => pc.createAnswer())
  .then((answer) => pc.setLocalDescription(answer))
  .then(() => {
    assert_not_equals(pc.sctp, null);
    canSendSize = pc.sctp.maxMessageSize == Number.POSITIVE_INFINITY ? 0 : pc.sctp.maxMessageSize;
    if (canSendSize != 0 && canSendSize < remoteValue2) {
      assert_unreached('This test needs two values that are less than canSendSize (unless it is zero)');
    }
  });
}, 'Determine the local side send limitation (canSendSize) by offering a max-message-size of 0');

promise_test(t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  assert_equals(pc.sctp, null);

  return generateDataChannelOffer(pc)
  .then((offer) => {
    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
      'SDP should have max-message-size attribute');

    // Remove the max-message-size SDP attribute
    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithoutAttribute(offer.sdp) };
    return pc.setRemoteDescription(offer)
  })
  .then(() => pc.createAnswer())
  .then((answer) => pc.setLocalDescription(answer))
  .then(() => {
    assert_not_equals(pc.sctp, null);
    // Test outcome depends on canSendSize value
    if (canSendSize) {
      assert_equals(pc.sctp.maxMessageSize, Math.min(65536, canSendSize),
        'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65536, canSendSize)');
    } else {
      assert_equals(pc.sctp.maxMessageSize, 65536,
        'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65536');
    }
  });
}, 'Remote offer SDP missing max-message-size attribute');

promise_test(t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  assert_equals(pc.sctp, null);

  return generateDataChannelOffer(pc)
  .then((offer) => {
    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
      'SDP should have max-message-size attribute');

    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) };
    return pc.setRemoteDescription(offer);
  })
  .then(() => pc.createAnswer())
  .then((answer) => pc.setLocalDescription(answer))
  .then(() => {
    assert_not_equals(pc.sctp, null);
    assert_equals(pc.sctp.maxMessageSize, remoteValue1,
      'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
  });
}, 'max-message-size with a (non-zero) value provided by the remote peer');

promise_test(t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  assert_equals(pc.sctp, null);

  return generateDataChannelOffer(pc)
  .then((offer) => {
    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
      'SDP should have max-message-size attribute');

    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) };
    return pc.setRemoteDescription(offer)
  })
  .then(() => pc.createAnswer())
  .then((answer) => pc.setLocalDescription(answer))
  .then(() => {
    assert_not_equals(pc.sctp, null);
    assert_equals(pc.sctp.maxMessageSize, remoteValue1,
      'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
  })
  .then(() => pc.createOffer()) // Start new O/A exchange that updates max-message-size
  .then((offer) => {
    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue2)};
    return pc.setRemoteDescription(offer)
  })
  .then(() => pc.createAnswer())
  .then((answer) => pc.setLocalDescription(answer))
  .then(() => {
    assert_not_equals(pc.sctp, null);
    assert_equals(pc.sctp.maxMessageSize, remoteValue2,
      'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)');
  })
  ;
}, 'Renegotiate max-message-size with a (non-zero) value provided by the remote peer');

promise_test(t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  assert_equals(pc.sctp, null);
  const largerThanCanSendSize = canSendSize + 1;

  return generateDataChannelOffer(pc)
  .then((offer) => {
    assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
      'SDP should have max-message-size attribute');

    offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, largerThanCanSendSize) };
    return pc.setRemoteDescription(offer)
  })
  .then(() => pc.createAnswer())
  .then((answer) => pc.setLocalDescription(answer))
  .then(() => {
    assert_not_equals(pc.sctp, null);
    // Test outcome depends on canSendSize value
    if (canSendSize) {
      assert_equals(pc.sctp.maxMessageSize, canSendSize,
        'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize');
    } else {
      assert_equals(pc.sctp.maxMessageSize, 65536,
        'A canSendSize of zero should let the remote value set maxMessageSize');
    }
  });
}, 'max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer');

</script>
