'use strict';

// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)

/**
 * Module dependencies.
 */

const spawn = require('child_process').spawn;
const fs = require('fs');
const path = require('path');
const os = require('os');

const exists = fs.existsSync || path.existsSync;
let cmd;

function which(name) {
  const paths = process.env.PATH.split(':');
  let loc;

  for (let i = 0, len = paths.length; i < len; i += 1) {
    loc = path.join(paths[i], name);
    if (exists(loc)) return loc;
  }
  return false;
}

function setupCmd() {
  switch (os.type()) {
    case 'Darwin':
      if (which('terminal-notifier')) {
        cmd = {
          type: 'Darwin-NotificationCenter',
          pkg: 'terminal-notifier',
          msg: '-message',
          title: '-title',
          subtitle: '-subtitle',
          icon: '-appIcon',
          sound: '-sound',
          url: '-open',
          priority: {
            cmd: '-execute',
            range: [],
          },
        };
      } else {
        cmd = {
          type: 'Darwin-Growl',
          pkg: 'growlnotify',
          msg: '-m',
          sticky: '--sticky',
          url: '--url',
          priority: {
            cmd: '--priority',
            range: [
              -2,
              -1,
              0,
              1,
              2,
              'Very Low',
              'Moderate',
              'Normal',
              'High',
              'Emergency',
            ],
          },
        };
      }
      break;
    case 'Linux':
      if (which('growl')) {
        cmd = {
          type: 'Linux-Growl',
          pkg: 'growl',
          msg: '-m',
          title: '-title',
          subtitle: '-subtitle',
          host: {
            cmd: '-H',
            hostname: '192.168.33.1',
          },
        };
      } else {
        cmd = {
          type: 'Linux',
          pkg: 'notify-send',
          msg: '',
          sticky: '-t',
          icon: '-i',
          priority: {
            cmd: '-u',
            range: [
              'low',
              'normal',
              'critical',
            ],
          },
        };
      }
      break;
    case 'Windows_NT':
      cmd = {
        type: 'Windows',
        pkg: 'growlnotify',
        msg: '',
        sticky: '/s:true',
        title: '/t:',
        icon: '/i:',
        url: '/cu:',
        priority: {
          cmd: '/p:',
          range: [
            -2,
            -1,
            0,
            1,
            2,
          ],
        },
      };
      break;
    default:
      break;
  }
}


/**
 * Send growl notification _msg_ with _options_.
 *
 * Options:
 *
 *  - title   Notification title
 *  - sticky  Make the notification stick (defaults to false)
 *  - priority  Specify an int or named key (default is 0)
 *  - name    Application name (defaults to growlnotify)
 *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects)
 *            works only in OSX > 10.8x
 *  - image
 *    - path to an icon sets --iconpath
 *    - path to an image sets --image
 *    - capitalized word sets --appIcon
 *    - filename uses extname as --icon
 *    - otherwise treated as --icon
 *
 * Examples:
 *
 *   growl('New email')
 *   growl('5 new emails', { title: 'Thunderbird' })
 *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })
 *   growl('Email sent', function(){
 *     // ... notification sent
 *   })
 *
 * @param {string} msg
 * @param {object} opts
 * @param {function} callback
 * @api public
 */

function growl(msg, opts, callback) {
  let image;
  const options = opts || {};
  const fn = callback || function noop() {};

  setupCmd();

  if (options.exec) {
    cmd = {
      type: 'Custom',
      pkg: options.exec,
      range: [],
    };
  }

  // noop
  if (!cmd) {
    fn(new Error('growl not supported on this platform'));
    return;
  }
  const args = [cmd.pkg];

  // image
  if (image || options.image) {
    image = options.image;
    switch (cmd.type) {
      case 'Darwin-Growl': {
        let flag;
        const ext = path.extname(image).substr(1);
        flag = ext === 'icns' && 'iconpath';
        flag = flag || (/^[A-Z]/.test(image) && 'appIcon');
        flag = flag || (/^png|gif|jpe?g$/.test(ext) && 'image');
        flag = flag || (ext && (image = ext) && 'icon');
        flag = flag || 'icon';
        args.push(`--${flag}`, image);
        break;
      }
      case 'Darwin-NotificationCenter':
        args.push(cmd.icon, image);
        break;
      case 'Linux':
        args.push(cmd.icon, image);
        // libnotify defaults to sticky, set a hint for transient notifications
        if (!options.sticky) args.push('--hint=int:transient:1');
        break;
      case 'Windows':
        args.push(cmd.icon + image);
        break;
      default:
        break;
    }
  }

  // sticky
  if (options.sticky) args.push(cmd.sticky);
  if (options.sticky && cmd.type === 'Linux') args.push('0');

  // priority
  if (options.priority) {
    const priority = `${options.priority}`;
    const checkindexOf = cmd.priority.range.indexOf(priority);
    if (checkindexOf > -1) {
      args.push(cmd.priority, options.priority);
    }
  }

  // sound
  if (options.sound && cmd.type === 'Darwin-NotificationCenter') {
    args.push(cmd.sound, options.sound);
  }

  // name
  if (options.name && cmd.type === 'Darwin-Growl') {
    args.push('--name', options.name);
  }

  switch (cmd.type) {
    case 'Darwin-Growl':
      args.push(cmd.msg);
      args.push(msg.replace(/\\n/g, '\n'));
      if (options.title) args.push(options.title);
      if (options.url) {
        args.push(cmd.url);
        args.push(options.url);
      }
      break;
    case 'Darwin-NotificationCenter': {
      args.push(cmd.msg);
      const stringifiedMsg = msg;
      const escapedMsg = stringifiedMsg.replace(/\\n/g, '\n');
      args.push(escapedMsg);
      if (options.title) {
        args.push(cmd.title);
        args.push(options.title);
      }
      if (options.subtitle) {
        args.push(cmd.subtitle);
        args.push(options.subtitle);
      }
      if (options.url) {
        args.push(cmd.url);
        args.push(options.url);
      }
      break;
    }
    case 'Linux-Growl':
      args.push(cmd.msg);
      args.push(msg.replace(/\\n/g, '\n'));
      if (options.title) args.push(options.title);
      if (cmd.host) {
        args.push(cmd.host.cmd, cmd.host.hostname);
      }
      break;
    case 'Linux':
      if (options.title) args.push(options.title);
      args.push(msg.replace(/\\n/g, '\n'));
      break;
    case 'Windows':
      args.push(msg.replace(/\\n/g, '\n'));
      if (options.title) args.push(cmd.title + options.title);
      if (options.url) args.push(cmd.url + options.url);
      break;
    case 'Custom': {
      const customCmd = args[0];
      const message = options.title
        ? `${options.title}: ${msg}`
        : msg;
      let command = customCmd.replace(/(^|[^%])%s/g, `$1${message}`);
      const splitCmd = command.split(' ');
      if (splitCmd.length > 1) {
        command = splitCmd.shift();
        Array.prototype.push.apply(args, splitCmd);
      }
      if (customCmd.indexOf('%s') < 0) {
        args.push(message);
      }
      args[0] = command;
      break;
    }
    default:
      break;
  }
  const cmdToExec = args.shift();

  const child = spawn(cmdToExec, args);
  let stdout = '';
  let stderr = '';
  let error;

  const now = new Date();
  const timestamp = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}.${now.getMilliseconds()}`

  stderr += `[${timestamp}][node-growl] : Executed command '${cmdToExec}' with arguments '${args}'\n[stderr] : `;

  child.on('error', (err) => {
    console.error('An error occured.', err);
    error = err;
  });

  child.stdout.on('data', (data) => {
    stdout += data;
  });

  child.stderr.on('data', (data) => {
    stderr += data;
  });

  child.on('close', () => {
    if (typeof fn === 'function') {
      fn(error, stdout, stderr);
    }
  });
}

/**
 * Expose `growl`.
 */

module.exports = growl;
