// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Utils provide logging functions and other JS functions commonly used by the
// app and media players.
var Utils = new function() {
  this.titleChanged = false;
};

// Adds options to document element.
Utils.addOptions = function(elementID, keyValueOptions, disabledOptions) {
  disabledOptions = disabledOptions || [];
  var selectElement = document.getElementById(elementID);
  var keys = Object.keys(keyValueOptions);
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    var option = new Option(key, keyValueOptions[key]);
    option.title = keyValueOptions[key];
    if (disabledOptions.indexOf(key) >= 0)
      option.disabled = true;
    selectElement.options.add(option);
  }
};

Utils.convertToArray = function(input) {
  if (Array.isArray(input))
    return input;
  return [input];
};

Utils.convertToUint8Array = function(msg) {
  if (typeof msg == 'string') {
    var ans = new Uint8Array(msg.length);
    for (var i = 0; i < msg.length; i++) {
      ans[i] = msg.charCodeAt(i);
    }
    return ans;
  }
  // Assume it is an ArrayBuffer or ArrayBufferView. If it already is a
  // Uint8Array, this will just make a copy of the view.
  return new Uint8Array(msg);
};

// Encodes data (Uint8Array) into base64url string. There is no '=' padding,
// and the characters '-' and '_' must be used instead of '+' and '/',
// respectively.
Utils.base64urlEncode = function(data) {
  var result = btoa(String.fromCharCode.apply(null, data));
  return result.replace(/=+$/g, '').replace(/\+/g, '-').replace(/\//g, '_');
};

Utils.createJWKData = function(keyId, key) {
  // JWK routines copied from third_party/WebKit/LayoutTests/media/
  //   encrypted-media/encrypted-media-utils.js

  // Creates a JWK from raw key ID and key.
  function createJWK(keyId, key) {
    var jwk = '{"kty":"oct","alg":"A128KW","kid":"';
    jwk += Utils.base64urlEncode(Utils.convertToUint8Array(keyId));
    jwk += '","k":"';
    jwk += Utils.base64urlEncode(Utils.convertToUint8Array(key));
    jwk += '"}';
    return jwk;
  }

  // Creates a JWK Set from an array of JWK(s).
  function createJWKSet() {
    var jwkSet = '{"keys":[';
    for (var i = 0; i < arguments.length; i++) {
      if (i != 0)
        jwkSet += ',';
      jwkSet += arguments[i];
    }
    jwkSet += ']}';
    return jwkSet;
  }

  return Utils.convertToUint8Array(createJWKSet(createJWK(keyId, key)));
};

Utils.createKeyIdsInitializationData = function(keyId) {
  var initData = '{"kids":["';
  initData += Utils.base64urlEncode(Utils.convertToUint8Array(keyId));
  initData += '"]}';
  return Utils.convertToUint8Array(initData);
};

function convertToString(data) {
  return String.fromCharCode.apply(null, Utils.convertToUint8Array(data));
}

Utils.extractFirstLicenseKeyId = function(message) {
  // Decodes data (Uint8Array) from base64url string.
  function base64urlDecode(data) {
    return atob(data.replace(/\-/g, "+").replace(/\_/g, "/"));
  }

  try {
    var json = JSON.parse(convertToString(message));
    // Decode the first element of 'kids', return it as an Uint8Array.
    return Utils.convertToUint8Array(base64urlDecode(json.kids[0]));
  } catch (error) {
    // Not valid JSON, so return message untouched as Uint8Array.
    return Utils.convertToUint8Array(message);
  }
};

Utils.verifyUsageRecord =
    function(message, expectNullTime) {
  try {
    var json = JSON.parse(convertToString(message));
    if (expectNullTime && (json.firstTime != null || json.latestTime != null)) {
      Utils.failTest(
          'Expecting null time for usage record but got firstTime=' +
          json.firstTime + ', latestTime=' + json.latestTime);
    } else if (!expectNullTime) {
      var first_decrypt_time = new Date(json.firstTime);
      var last_decrypt_time = new Date(json.latestTime);
      Utils.timeLog('First decrypt time: ' + first_decrypt_time.toISOString());
      Utils.timeLog('Last decrypt time: ' + last_decrypt_time.toISOString());

      var delta = json.latestTime - json.firstTime;
      // The video used for the tests is roughly 2.5 seconds.
      if (delta < 2000 || delta > 3000) {
        Utils.failTest(
            'The usage record reported by the CDM was not in the ' +
            'expected range')
      }
    }

  } catch (error) {
    Utils.failTest(
        'Fail to extract first decrypt time from license-release' +
        'message');
  }
}

    Utils.documentLog = function(log, success, time) {
  if (!docLogs)
    return;
  time = time || Utils.getCurrentTimeString();
  var timeLog = '<span style="color: green">' + time + '</span>';
  var logColor = !success ? 'red' : 'black'; // default is true.
  log = '<span style="color: "' + logColor + '>' + log + '</span>';
  docLogs.innerHTML = timeLog + ' - ' + log + '<br>' + docLogs.innerHTML;
};

Utils.ensureOptionInList = function(listID, option) {
  var selectElement = document.getElementById(listID);
  for (var i = 0; i < selectElement.length; i++) {
    if (selectElement.options[i].value == option) {
      selectElement.value = option;
      return;
    }
  }
  // The list does not have the option, let's add it and select it.
  var optionElement = new Option(option, option);
  optionElement.title = option;
  selectElement.options.add(optionElement);
  selectElement.value = option;
};

Utils.failTest = function(msg, newTitle) {
  var failMessage = 'FAIL: ';
  var title = 'FAILED';
  // Handle exception messages;
  if (msg.message) {
    title = msg.name || 'Error';
    failMessage += title + ' ' + msg.message;
  } else if (msg instanceof Event) {
    // Handle failing events.
    failMessage = msg.target + '.' + msg.type;
    title = msg.type;
  } else {
    failMessage += msg;
  }
  // Force newTitle if passed.
  title = newTitle || title;
  // Log failure.
  Utils.documentLog(failMessage, false);
  console.log(failMessage, msg);
  Utils.setResultInTitle(title);
};

Utils.getCurrentTimeString = function() {
  var date = new Date();
  var hours = ('0' + date.getHours()).slice(-2);
  var minutes = ('0' + date.getMinutes()).slice(-2);
  var secs = ('0' + date.getSeconds()).slice(-2);
  var milliSecs = ('00' + date.getMilliseconds()).slice(-3);
  return hours + ':' + minutes + ':' + secs + '.' + milliSecs;
};

Utils.getDefaultKey = function(forceInvalidResponse) {
  if (forceInvalidResponse) {
    Utils.timeLog('Forcing invalid key data.');
    return new Uint8Array([0xAA]);
  }
  return KEY;
};

Utils.getHexString = function(uintArray) {
  var hex_str = '';
  for (var i = 0; i < uintArray.length; i++) {
    var hex = uintArray[i].toString(16);
    if (hex.length == 1)
      hex = '0' + hex;
    hex_str += hex;
  }
  return hex_str;
};

Utils.hasPrefix = function(msg, prefix) {
  var message = String.fromCharCode.apply(null, Utils.convertToUint8Array(msg));
  return message.substring(0, prefix.length) == prefix;
};

Utils.installTitleEventHandler = function(element, event) {
  element.addEventListener(event, function(e) {
    Utils.setResultInTitle(e.type.toUpperCase());
  }, false);
};

Utils.resetTitleChange = function() {
  this.titleChanged = false;
  document.title = '';
};

Utils.sendRequest = function(
    requestType, responseType, message, serverURL, onResponseCallbackFn,
    forceInvalidResponse) {
  var requestAttemptCount = 0;
  var REQUEST_RETRY_DELAY_MS = 3000;
  var REQUEST_TIMEOUT_MS = 1000;

  function sendRequestAttempt() {
    // No limit on the number of retries. This will retry on failures
    // until the test framework stops the test.
    requestAttemptCount++;
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.responseType = responseType;
    xmlhttp.open(requestType, serverURL, true);
    xmlhttp.onerror = function(e) {
      Utils.timeLog('Request status: ' + this.statusText);
      Utils.timeLog('FAILED: License request XHR failed with network error.');
      Utils.timeLog('Retrying request in ' + REQUEST_RETRY_DELAY_MS + 'ms');
      setTimeout(sendRequestAttempt, REQUEST_RETRY_DELAY_MS);
    };
    xmlhttp.onload = function(e) {
      if (this.status == 200) {
        onResponseCallbackFn(this.response);
      } else if (this.status == 404 && serverURL == DEFAULT_LICENSE_SERVER) {
        // If using the default license server, no page available means there
        // is no license server configured.
        onResponseCallbackFn(Utils.convertToUint8Array("No license."));
      } else {
        Utils.timeLog('Bad response status: ' + this.status);
        Utils.timeLog('Bad response: ' + this.response);
        Utils.timeLog('Retrying request in ' + REQUEST_RETRY_DELAY_MS + 'ms');
        setTimeout(sendRequestAttempt, REQUEST_RETRY_DELAY_MS);
      }
    };
    xmlhttp.timeout = REQUEST_TIMEOUT_MS;
    xmlhttp.ontimeout = function(e) {
      Utils.timeLog('Request timeout');
      Utils.timeLog('Retrying request in ' + REQUEST_RETRY_DELAY_MS + 'ms');
      setTimeout(sendRequestAttempt, REQUEST_RETRY_DELAY_MS);
    }
    Utils.timeLog('Attempt (' + requestAttemptCount +
                  '): sending request to server: ' + serverURL);
    xmlhttp.send(message);
  }

  if (forceInvalidResponse) {
    Utils.timeLog('Not sending request - forcing an invalid response.');
    return onResponseCallbackFn(Utils.convertToUint8Array("Invalid response."));
  }
  sendRequestAttempt();
};

Utils.setResultInTitle = function(title) {
  // If document title is 'ENDED', then update it with new title to possibly
  // mark a test as failure.  Otherwise, keep the first title change in place.
  if (!this.titleChanged || document.title == 'ENDED')
    document.title = title;
  Utils.timeLog('Set document title to: ' + title + ', updated title: ' +
                document.title);
  this.titleChanged = true;
};

Utils.timeLog = function(/**/) {
  if (arguments.length == 0)
    return;
  var time = Utils.getCurrentTimeString();
  // Log to document.
  Utils.documentLog(arguments[0], time);
  // Log to JS console.
  var logString = time + ' - ';
  for (var i = 0; i < arguments.length; i++) {
    logString += ' ' + arguments[i];
  }
  console.log(logString);
};

// Convert an event into a promise. When |event| is fired on |object|,
// call |func| to handle the event and either resolve or reject the promise.
// If |func| is not specified, the promise will simply be resolved with the
// event when the event happens.
Utils.waitForEvent = function(object, event, func) {
  return new Promise(function(resolve, reject) {
    object.addEventListener(event, function listener(e) {
      object.removeEventListener(event, listener);
      if (func) {
        func(e, resolve, reject);
      } else {
        // No |func| is specified, so simply resolve the promise passing
        // |event| in case the caller is interested in it.
        resolve(event);
      }
    });
  });
};

// Create a loadable session and return the session ID of it as a promise.
Utils.createSessionToLoad = function(mediaKeys, request) {
  // Create a persistent session and on the message event initialize it
  // with key ID |KEY_ID| and key |KEY|. Then close the session, and resolve
  // the promise providing the session ID.
  const keySession = mediaKeys.createSession('persistent-license');
  var promise =
      Utils.waitForEvent(keySession, 'message', function(e, resolve, reject) {
        const session = e.target;
        return session.update(Utils.createJWKData(KEY_ID, KEY))
            .then(function(result) {
              Utils.timeLog(
                  'Persistent session ' + session.sessionId + ' created');
              return session.close();
            })
            .then(function(result) {
              // Make sure the session is properly closed before continuing on.
              return session.closed;
            })
            .then(function(result) {
              Utils.timeLog(
                  'Persistent session ' + session.sessionId +
                  ' saved and closed');
              resolve(session.sessionId);
            });
      });
  return keySession
      .generateRequest('keyids', Utils.createKeyIdsInitializationData(KEY_ID))
      .then(function() {
        return promise;
      });
};

// Verify that |keyStatuses| contains just the keys in the array |expected|.
// Each entry specifies the keyId and status expected.
// Example call: verifyKeyStatuses(mediaKeySession.keyStatuses,
//   [{keyId: key1, status: 'usable'}, {keyId: key2, status: 'released'}]);
Utils.verifyKeyStatuses = function(keyStatuses, expected) {
  // |keyStatuses| should have same size as number of |keys.expected|.
  if (keyStatuses.size !== expected.length) {
    Utils.failTest(
        'keystatuses should have expected size of ' + expected.length +
        ' but has size ' + keyStatuses.size);
  }

  // All |expected| should be found.
  expected.map(function(item) {
    if (!keyStatuses.has(Utils.convertToUint8Array(item.keyId))) {
      Utils.failTest('missing keyID ' + item.keyId);
    }
    if (keyStatuses.get(Utils.convertToUint8Array(item.keyId)) !==
        item.status) {
      Utils.failTest(
          'keyId ' + item.keyId + ' has status ' +
          keyStatuses.get(Utils.convertToUint8Array(item.keyId)) +
          ', expected ' + item.status);
    }
  });
};
