/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/**
 * @fileoverview
 * @suppress {missingRequire}
 */

import {patchMethod, scheduleMacroTaskWithCurrentZone, zoneSymbol} from './utils';

const taskSymbol = zoneSymbol('zoneTask');

interface TimerOptions extends TaskData {
  handleId?: number;
  args: any[];
}

export function patchTimer(window: any, setName: string, cancelName: string, nameSuffix: string) {
  let setNative: Function|null = null;
  let clearNative: Function|null = null;
  setName += nameSuffix;
  cancelName += nameSuffix;

  const tasksByHandleId: {[id: number]: Task} = {};

  function scheduleTask(task: Task) {
    const data = <TimerOptions>task.data;
    function timer() {
      try {
        task.invoke.apply(this, arguments);
      } finally {
        // issue-934, task will be cancelled
        // even it is a periodic task such as
        // setInterval
        if (!(task.data && task.data.isPeriodic)) {
          if (typeof data.handleId === 'number') {
            // in non-nodejs env, we remove timerId
            // from local cache
            delete tasksByHandleId[data.handleId];
          } else if (data.handleId) {
            // Node returns complex objects as handleIds
            // we remove task reference from timer object
            (data.handleId as any)[taskSymbol] = null;
          }
        }
      }
    }
    data.args[0] = timer;
    data.handleId = setNative!.apply(window, data.args);
    return task;
  }

  function clearTask(task: Task) {
    return clearNative!((<TimerOptions>task.data).handleId);
  }

  setNative =
      patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) {
        if (typeof args[0] === 'function') {
          const options: TimerOptions = {
            isPeriodic: nameSuffix === 'Interval',
            delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 :
                                                                             undefined,
            args: args
          };
          const task =
              scheduleMacroTaskWithCurrentZone(setName, args[0], options, scheduleTask, clearTask);
          if (!task) {
            return task;
          }
          // Node.js must additionally support the ref and unref functions.
          const handle: any = (<TimerOptions>task.data).handleId;
          if (typeof handle === 'number') {
            // for non nodejs env, we save handleId: task
            // mapping in local cache for clearTimeout
            tasksByHandleId[handle] = task;
          } else if (handle) {
            // for nodejs env, we save task
            // reference in timerId Object for clearTimeout
            handle[taskSymbol] = task;
          }

          // check whether handle is null, because some polyfill or browser
          // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame
          if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' &&
              typeof handle.unref === 'function') {
            (<any>task).ref = (<any>handle).ref.bind(handle);
            (<any>task).unref = (<any>handle).unref.bind(handle);
          }
          if (typeof handle === 'number' || handle) {
            return handle;
          }
          return task;
        } else {
          // cause an error by calling it directly.
          return delegate.apply(window, args);
        }
      });

  clearNative =
      patchMethod(window, cancelName, (delegate: Function) => function(self: any, args: any[]) {
        const id = args[0];
        let task: Task;
        if (typeof id === 'number') {
          // non nodejs env.
          task = tasksByHandleId[id];
        } else {
          // nodejs env.
          task = id && id[taskSymbol];
          // other environments.
          if (!task) {
            task = id;
          }
        }
        if (task && typeof task.type === 'string') {
          if (task.state !== 'notScheduled' &&
              (task.cancelFn && task.data!.isPeriodic || task.runCount === 0)) {
            if (typeof id === 'number') {
              delete tasksByHandleId[id];
            } else if (id) {
              id[taskSymbol] = null;
            }
            // Do not cancel already canceled functions
            task.zone.cancelTask(task);
          }
        } else {
          // cause an error by calling it directly.
          delegate.apply(window, args);
        }
      });
}
