// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Run the JSON deserialize algorithm on the value.
// https://www.w3.org/TR/webdriver/#dfn-json-deserialize
webdriverExecutor.deserialize = function(value) {
  if (value instanceof Array) {
    // Deserialize each of the array's values;
    var deserializedArray = [];
    var numArgs = value.length;
    for (var i = 0; i < numArgs; i++) {
      deserializedArray.push(webdriverExecutor.deserialize(value[i]));
    }
    return deserializedArray;
  } else if (value instanceof Object && value.ELEMENT) {
    // The argument is a WebElement, as denoted by the presence of the
    // ELEMENT property, so get the actual Element the id is mapped to.
    return webdriverExecutor.idToElement(value.ELEMENT);
  } else if (value instanceof Object) {
    // Deserialize each of the object's values.
    var deserializedObject = {};
    for (var key in value) {
      deserializedObject[key] = webdriverExecutor.deserialize(value[key]);
    }
    return deserializedObject;
  }
  return value;
};

// Run the JSON clone algorithm on the value.
// https://www.w3.org/TR/webdriver/#dfn-internal-json-clone-algorithm
webdriverExecutor.serialize = function(value, seen) {
  if (value === undefined || value === null) {
    return null;
  } else if (value instanceof Element) {
    var webElementId = webdriverExecutor.elementToId(value);
    return { "ELEMENT": webElementId };
  } else if (value instanceof Object) {
    if (seen.indexOf(value) != -1) {
      throw "Reference cycle found trying to serialize.";
    }
    seen.push(value);
    if (value instanceof Array || value instanceof NodeList
        || value instanceof HTMLCollection) {
      var serializedArray = [];
      var length = value.length;
      for (var i = 0; i < length; i++) {
        serializedArray.push(webdriverExecutor.serialize(value[i], seen));
      }
      return serializedArray;
    } else {
      // Deserialize each of the object's its values.
      var serializedObject = {};
      for (var key in value) {
        serializedObject[key] = webdriverExecutor.serialize(value[key], seen);
      }
      return serializedObject;
    }
  }
  return value;
};

// Set the executeScriptHarness callback function.
// The function takes a functionObject and a JSON string representing an array
// of arguments. The arguments are applied to the function |functionObject|.
webdriverExecutor.executeScriptHarness = function(params, resultHandler) {
  var parameters = webdriverExecutor.deserialize(JSON.parse(params.jsonArgs));
  if (params.asyncTimeout === null) {
    var result = params.functionObject.apply(window, parameters);
    resultHandler.onResult(JSON.stringify(webdriverExecutor.serialize(result, [])));
  } else {
    var timeoutCallback = function() {
      resultHandler.onTimeout();
    }
    var timerId = window.setTimeout(timeoutCallback, params.asyncTimeout);

    var resultCallback = function(result) {
      resultHandler.onResult(JSON.stringify(webdriverExecutor.serialize(result, [])));
      window.clearTimeout(timerId);
    }
    parameters.push(resultCallback);
    params.functionObject.apply(window, parameters);
  }
};
