'use strict';

// Code is based on the following editor draft:
//   https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

/*
  mock-idp.js is a naive IdP that provides absolutely no
  security for authentication. It can generate identity
  assertion for whatever identity that is requested.

  mock-idp.js validates identity assertion by simply decoding
  the JSON and return whatever that is inside, with no integrity
  protection and thus can be spoofed by anyone.

  While being not practical at all, mock-idp.js allows us
  to test various aspects of the identity API and allow tests
  to manipulate the IdP at will.
 */

// We pass around test options as query string to instruct
// the test IdP proxy script on what actions to perform.
// This hack is based on the fact that query string is allowed
// when specifying the IdP protocol.
function parseQueryString(urlStr) {
  const url = new URL(urlStr);
  const result = {};
  for(const [key, value] of url.searchParams) {
    result[key] = value;
  }
  return result;
}

/*
  9.2.1.  Interface Exposed by Identity Providers
    callback GenerateAssertionCallback =
      Promise<RTCIdentityAssertionResult> (
        DOMString contents,
        DOMString origin,
        RTCIdentityProviderOptions options);

    dictionary RTCIdentityProviderOptions {
      DOMString protocol = "default";
      DOMString usernameHint;
      DOMString peerIdentity;
    };

    dictionary RTCIdentityAssertionResult {
      required RTCIdentityProviderDetails idp;
      required DOMString                  assertion;
    };

    dictionary RTCIdentityProviderDetails {
      required DOMString domain;
               DOMString protocol = "default";
    };
 */

const query = parseQueryString(location);

// Generate a naive identity assertion. The result assertion
// is a JSON string that report the various parameters
// received by this function.
//   watermark - a special mark to make sure the result is returned
//               from this function
//   args - the function arguments received
//   env - some global variable values when this function is called
//   query - the parsed query string of the script URL
function generateAssertion(contents, origin, options) {
  const args = {
    contents, origin, options
  };

  const env = {
    origin,
    location
  };

  const assertion = {
    watermark: 'mock-idp.js.watermark',
    args,
    env,
    query
  };

  const assertionStr = JSON.stringify(assertion);

  const { generatorAction } = query;

  if(generatorAction === 'throw-error') {
    const err = new Error('Mock Internal IdP Error');
    err.idpErrorInfo = query.errorInfo;
    throw err;

  } else if(generatorAction === 'require-login') {
    const err = new RTCError('idp-need-login');
    err.idpLoginUrl = `${origin}/login`;
    err.idpErrorInfo = 'login required';
    throw err;

  } else if(generatorAction === 'return-custom-idp') {
    const { domain, protocol } = query;

    return {
      idp: {
        domain,
        protocol
      },
      assertion: assertionStr
    };

  } else if(generatorAction === 'return-invalid-result') {
    return 'invalid-result';

  } else {
    return {
      idp: {
        domain: location.host,
        protocol: 'mock-idp.js'
      },
      assertion: assertionStr
    };
  }
}

/*
  9.2.1.  Interface Exposed by Identity Providers
    callback ValidateAssertionCallback =
      Promise<RTCIdentityValidationResult> (
        DOMString assertion,
        DOMString origin);

    dictionary RTCIdentityValidationResult {
      required DOMString identity;
      required DOMString contents;
    };
 */
function validateAssertion(assertionStr, origin) {
  const assertion = JSON.parse(assertionStr);

  const { args, query } = assertion;
  const { contents, options } = args;

  const identity = options.usernameHint;

  const {
    validatorAction
  } = query;

  if(validatorAction === 'throw-error') {
    const err = new Error('Mock Internal IdP Error');
    err.idpErrorInfo = query.errorInfo;
    throw err;

  } else if(validatorAction === 'return-custom-contents') {
    const { contents } = query;
    return {
      identity,
      contents
    };

  } else {
    return {
      identity, contents
    };
  }
}

/*
  9.2.  Registering an IdP Proxy
    [Global,
     Exposed=RTCIdentityProviderGlobalScope]
    interface RTCIdentityProviderGlobalScope : WorkerGlobalScope {
      readonly attribute RTCIdentityProviderRegistrar rtcIdentityProvider;
    };

    [Exposed=RTCIdentityProviderGlobalScope]
    interface RTCIdentityProviderRegistrar {
      void register(RTCIdentityProvider idp);
    };

    dictionary RTCIdentityProvider {
      required GenerateAssertionCallback generateAssertion;
      required ValidateAssertionCallback validateAssertion;
    };
 */

// if rtcIdentityProvider is defined, and the caller do not ask
// to not register through query string, register our assertion callbacks.
if(rtcIdentityProvider && query.action !== 'do-not-register') {
  rtcIdentityProvider.register({
    generateAssertion,
    validateAssertion
  });
}
