<!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="../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());

    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>
