/**
 * @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
 */

import './node_util';
import './events';
import './fs';

import {findEventTasks} from '../common/events';
import {patchTimer} from '../common/timers';
import {ArraySlice, isMix, patchMacroTask, patchMicroTask} from '../common/utils';

const set = 'set';
const clear = 'clear';

Zone.__load_patch('node_timers', (global: any, Zone: ZoneType) => {
  // Timers
  let globalUseTimeoutFromTimer = false;
  try {
    const timers = require('timers');
    let globalEqualTimersTimeout = global.setTimeout === timers.setTimeout;
    if (!globalEqualTimersTimeout && !isMix) {
      // 1. if isMix, then we are in mix environment such as Electron
      // we should only patch timers.setTimeout because global.setTimeout
      // have been patched
      // 2. if global.setTimeout not equal timers.setTimeout, check
      // whether global.setTimeout use timers.setTimeout or not
      const originSetTimeout = timers.setTimeout;
      timers.setTimeout = function() {
        globalUseTimeoutFromTimer = true;
        return originSetTimeout.apply(this, arguments);
      };
      const detectTimeout = global.setTimeout(() => {}, 100);
      clearTimeout(detectTimeout);
      timers.setTimeout = originSetTimeout;
    }
    patchTimer(timers, set, clear, 'Timeout');
    patchTimer(timers, set, clear, 'Interval');
    patchTimer(timers, set, clear, 'Immediate');
  } catch (error) {
    // timers module not exists, for example, when we using nativeScript
    // timers is not available
  }
  if (isMix) {
    // if we are in mix environment, such as Electron,
    // the global.setTimeout has already been patched,
    // so we just patch timers.setTimeout
    return;
  }
  if (!globalUseTimeoutFromTimer) {
    // 1. global setTimeout equals timers setTimeout
    // 2. or global don't use timers setTimeout(maybe some other library patch setTimeout)
    // 3. or load timers module error happens, we should patch global setTimeout
    patchTimer(global, set, clear, 'Timeout');
    patchTimer(global, set, clear, 'Interval');
    patchTimer(global, set, clear, 'Immediate');
  } else {
    // global use timers setTimeout, but not equals
    // this happens when use nodejs v0.10.x, global setTimeout will
    // use a lazy load version of timers setTimeout
    // we should not double patch timer's setTimeout
    // so we only store the __symbol__ for consistency
    global[Zone.__symbol__('setTimeout')] = global.setTimeout;
    global[Zone.__symbol__('setInterval')] = global.setInterval;
    global[Zone.__symbol__('setImmediate')] = global.setImmediate;
  }
});

// patch process related methods
Zone.__load_patch('nextTick', () => {
  // patch nextTick as microTask
  patchMicroTask(process, 'nextTick', (self: any, args: any[]) => {
    return {
      name: 'process.nextTick',
      args: args,
      cbIdx: (args.length > 0 && typeof args[0] === 'function') ? 0 : -1,
      target: process
    };
  });
});

Zone.__load_patch(
    'handleUnhandledPromiseRejection', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
      (Zone as any)[api.symbol('unhandledPromiseRejectionHandler')] =
          findProcessPromiseRejectionHandler('unhandledRejection');

      (Zone as any)[api.symbol('rejectionHandledHandler')] =
          findProcessPromiseRejectionHandler('rejectionHandled');

      // handle unhandled promise rejection
      function findProcessPromiseRejectionHandler(evtName: string) {
        return function(e: any) {
          const eventTasks = findEventTasks(process, evtName);
          eventTasks.forEach(eventTask => {
            // process has added unhandledrejection event listener
            // trigger the event listener
            if (evtName === 'unhandledRejection') {
              eventTask.invoke(e.rejection, e.promise);
            } else if (evtName === 'rejectionHandled') {
              eventTask.invoke(e.promise);
            }
          });
        };
      }
    });


// Crypto
Zone.__load_patch('crypto', () => {
  let crypto: any;
  try {
    crypto = require('crypto');
  } catch (err) {
  }

  // use the generic patchMacroTask to patch crypto
  if (crypto) {
    const methodNames = ['randomBytes', 'pbkdf2'];
    methodNames.forEach(name => {
      patchMacroTask(crypto, name, (self: any, args: any[]) => {
        return {
          name: 'crypto.' + name,
          args: args,
          cbIdx: (args.length > 0 && typeof args[args.length - 1] === 'function') ?
              args.length - 1 :
              -1,
          target: crypto
        };
      });
    });
  }
});

Zone.__load_patch('console', (global: any, Zone: ZoneType) => {
  const consoleMethods =
      ['dir', 'log', 'info', 'error', 'warn', 'assert', 'debug', 'timeEnd', 'trace'];
  consoleMethods.forEach((m: string) => {
    const originalMethod = (console as any)[Zone.__symbol__(m)] = (console as any)[m];
    if (originalMethod) {
      (console as any)[m] = function() {
        const args = ArraySlice.call(arguments);
        if (Zone.current === Zone.root) {
          return originalMethod.apply(this, args);
        } else {
          return Zone.root.run(originalMethod, this, args);
        }
      };
    }
  });
});
