<!doctype html>
<meta charset=utf-8>
<title>RTCRtpTransceiver with OfferToReceive legacy options</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src='/mediacapture-streams/permission-helper.js'></script>
<script src="../RTCPeerConnection-helper.js"></script>
<script>
  'use strict';

  const stopTracks = (...streams) => {
    streams.forEach(stream => stream.getTracks().forEach(track => track.stop()));
  };

  // comparable() - produces copy of object that is JSON comparable.
  // o = original object (required)
  // t = template of what to examine. Useful if o is non-enumerable (optional)

  const comparable = (o, t = o) => {
    if (typeof o != 'object' || !o) {
      return o;
    }
    if (Array.isArray(t) && Array.isArray(o)) {
      return o.map((n, i) => comparable(n, t[i]));
    }
    return Object.keys(t).sort()
        .reduce((r, key) => (r[key] = comparable(o[key], t[key]), r), {});
  };

  const stripKeyQuotes = s => s.replace(/"(\w+)":/g, "$1:");

  const hasProps = (observed, expected) => {
    const observable = comparable(observed, expected);
    assert_equals(stripKeyQuotes(JSON.stringify(observable)),
       stripKeyQuotes(JSON.stringify(comparable(expected))));
  };

  const checkAddTransceiverWithStream = async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    await setMediaPermission();
    const audioStream = await navigator.mediaDevices.getUserMedia({audio: true});
    const videoStream = await navigator.mediaDevices.getUserMedia({video: true});
    t.add_cleanup(() => stopTracks(audioStream, videoStream));

    const audio = audioStream.getAudioTracks()[0];
    const video = videoStream.getVideoTracks()[0];

    pc.addTransceiver(audio, {streams: [audioStream]});
    pc.addTransceiver(video, {streams: [videoStream]});

    hasProps(pc.getTransceivers(),
      [
        {
          receiver: {track: {kind: "audio"}},
          sender: {track: audio},
          direction: "sendrecv",
          mid: null,
          currentDirection: null,
          stopped: false
        },
        {
          receiver: {track: {kind: "video"}},
          sender: {track: video},
          direction: "sendrecv",
          mid: null,
          currentDirection: null,
          stopped: false
        }
      ]);

    const offer = await pc.createOffer();
    assert_true(offer.sdp.includes("a=msid:" + audioStream.id),
      "offer contains the expected audio msid");
    assert_true(offer.sdp.includes("a=msid:" + videoStream.id),
      "offer contains the expected video msid");
  };

  const checkAddTransceiverWithOfferToReceive = async (t, kinds) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());

    const propsToSet = kinds.map(kind => {
      if (kind == "audio") {
        return "offerToReceiveAudio";
      } else if (kind == "video") {
        return "offerToReceiveVideo";
      }
    });

    const options = {};

    for (const prop of propsToSet) {
      options[prop] = true;
    }

    let offer = await pc.createOffer(options);

    const expected = [];

    if (options.offerToReceiveAudio) {
      expected.push(
        {
          receiver: {track: {kind: "audio"}},
          sender: {track: null},
          direction: "recvonly",
          mid: null,
          currentDirection: null,
          stopped: false
        });
    }

    if (options.offerToReceiveVideo) {
      expected.push(
        {
          receiver: {track: {kind: "video"}},
          sender: {track: null},
          direction: "recvonly",
          mid: null,
          currentDirection: null,
          stopped: false
        });
    }

    hasProps(pc.getTransceivers(), expected);

    // Test offerToReceive: false
    for (const prop of propsToSet) {
      options[prop] = false;
    }

    // Check that sendrecv goes to sendonly
    for (const transceiver of pc.getTransceivers()) {
      transceiver.direction = "sendrecv";
    }

    for (const transceiverCheck of expected) {
      transceiverCheck.direction = "sendonly";
    }

    offer = await pc.createOffer(options);
    hasProps(pc.getTransceivers(), expected);

    // Check that recvonly goes to inactive
    for (const transceiver of pc.getTransceivers()) {
      transceiver.direction = "recvonly";
    }

    for (const transceiverCheck of expected) {
      transceiverCheck.direction = "inactive";
    }

    offer = await pc.createOffer(options);
    hasProps(pc.getTransceivers(), expected);
  };

const tests = [
  checkAddTransceiverWithStream,
  function checkAddTransceiverWithOfferToReceiveAudio(t) {
    return checkAddTransceiverWithOfferToReceive(t, ["audio"]);
  },
  function checkAddTransceiverWithOfferToReceiveVideo(t) {
    return checkAddTransceiverWithOfferToReceive(t, ["video"]);
  },
  function checkAddTransceiverWithOfferToReceiveBoth(t) {
    return checkAddTransceiverWithOfferToReceive(t, ["audio", "video"]);
  }
].forEach(test => promise_test(test, test.name));

</script>
