<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
<script src="../xr/resources/xr-internal-device-mocking.js"></script>
<script src="../xr/resources/xr-test-utils.js"></script>
<script src="../xr/resources/test-constants.js"></script>
<canvas id="webgl-canvas"></canvas>

<script>

let testName = "Outstanding promises resolve appropriately if device disconencts";

// Expose the ability to get get the VRService and close the device on that VRService.
ChromeXRTest.prototype.getService = function() {
  return this.mockVRService_;
}

MockVRService.prototype.closeDevice = function() {
  this.deviceBinding_.close();
  this.devicePtr_ = null;
}

// Override the default implementations of requestSession and supportsSession
// from XRDevice so that we can choose to either return an answer immediately or
// return a promise that will never resolve to guarantee we have an outstanding
// promise on device disconnect.
MockVRService.prototype.requestSession = function(sessionOptions, was_activation) {
  return new Promise((resolve,reject) => { });
}

let immediatelyResolveSupportsSession = true;
MockVRService.prototype.supportsSession = function(sessionOptions) {
  if (immediatelyResolveSupportsSession) {
    return Promise.resolve({ supportsSession: true });
  }

  return new Promise((resolve, reject) => { });
}

// Override the default requestDevice implementation so that we can fail if it's
// called when we don't expect it to be called (typically this would be because
// we aren't planning to force another device closure and would leave any
// outstanding promises unresolved, and thus cause the test to timeout), and so
// that we can store the device binding so that we can force it to be closed.
let failIfRequestDeviceCalled = false;
MockVRService.prototype.requestDevice = function() {
  if (failIfRequestDeviceCalled) {
    assert_unreached("requestDevice shouldn't be called at this time");
  }

  if (!this.devicePtr_) {
    this.devicePtr_ = new device.mojom.XRDevicePtr();
    this.deviceBinding_ = new mojo.Binding(
        device.mojom.XRDevice, this, mojo.makeRequest(this.devicePtr_));
  }

  return Promise.resolve({device: this.devicePtr_});
}

// Convenience methods to turn a resolve/reject into an appropraite string
// which Promise.All can check to tell us which methods failed.
// If we just let the promises assert, then Promise.all would only fail on the
// first assert.
let successMessage = "PASS";
let failMessageStart = "FAIL: "
function WrapResolve(promise, name, errorMsg) {
  return promise.then(() => {
    return successMessage;
  }, () => {
    return failMessageStart + name + ": " + errorMsg;
  });
}

function WrapReject(promise, name, errorMsg, errorType) {
  return promise.then(() => {
    return failMessageStart + name + ": " + errorMsg;
  }, (err) => {
    if (err.name === errorType) {
      return successMessage;
    }

    return failMessageStart + name + ": expected: " + errorType + " but got: " + err.name;
  });
}

// Per security requirements, requesting an immersive session requires a user gesture.
function requestImmersiveSession() {
  return new Promise((resolve, reject) => {
    runWithUserGesture(() => {
      navigator.xr.requestSession('immersive-vr').then((session) => {
        resolve(session);
      }, (err) => {
        reject(err);
      });
    });
  });
}

let validateDeviceDisconnectPromise = function() {
  // Ensure that the state is properly set-up for our helper functions so that
  // we can be called multiple times.
  failIfRequestDeviceCalled = false;
  immediatelyResolveSupportsSession = true;

  // Make a supports session call so that we can ensure that the underlying code
  // has gotten a devicePtr set up.  Note that inline, since it's always
  // guaranteed doesn't ensure that the device is set up, where-as a call to see
  // if we support immersive does require a device
  return navigator.xr.supportsSession('immersive-vr').then(() => {

    // Cause supportsSession to stop returning and make future calls "hang"/
    immediatelyResolveSupportsSession = false;

    // We don't expect a new device to be requested, and if it is we aren't
    // going to close it during this test, so any of our mocked calls will cause
    //  a timeout.
    failIfRequestDeviceCalled = true;
    let promises = [];

    // Note that inline session requests still call out through the device.
    promises.push(WrapResolve(navigator.xr.requestSession('inline'), "Request Inline",
      "Inline should always be available"));
    promises.push(WrapReject(requestImmersiveSession(), "Request Immersive",
      "Immersive should be rejected once device is disconnected", "NotSupportedError"));
    promises.push(WrapReject(navigator.xr.supportsSession('immersive-vr'), "Supports Immersive",
      "Immersive should not be supported once device is disconnected", "NotSupportedError"));

    // Force the device disconnect, which should cause the promises to resolve.
    XRTest.getService().closeDevice();

    // Call this after we close the device, because we don't expect this to rely
    // on (or request) the presence of a device.
    promises.push(WrapResolve(navigator.xr.supportsSession('inline'), "Supports Inline",
      "Inline support should be available without calling to a device"));

    return Promise.all(promises).then((results) => {
      let error_messages = [];
      for (let i = 0; i < results.length; i++) {
        if (results[i] !== successMessage) {
          error_messages.push(results[i]);
        }
      }

      if (error_messages.length !== 0) {
        assert_unreached(error_messages);
      }
    })
  });
}

let testFunction = function(t) {
  return validateDeviceDisconnectPromise().then(() => {

    // Validate that even after disconnecting and resolving the promises,
    // we can still request a new device, and that it will resolve any promises
    // on it's disconnect.
    return validateDeviceDisconnectPromise();
  })
}

promise_test(testFunction, testName);

</script>
