/**
 * Copyright (c) 2012 Andreas Madsen
 * MIT License
 */

(function () {
  "use strict";

  var util = require('util');
  var fs = require('fs');
  var path = require('path');

  var immortal = require('./module.js');

  function Monitor() {
    immortal.MonitorAbstract.apply(this, arguments);
    var self = this;

    // create a write stream, the file path was checked by exports.check
    this.stream = fs.createWriteStream(this.options.output);

    // stdout and stderr streams do already exist before the process
    // is spawned. Note the process spawn when calling this.ready method.
    this.stdout.pipe(this.stream);
    this.stderr.pipe(this.stream);

    // create a write wrapper method
    this.write = function (text) {
      self.stream.write(text + '\n');
    };

    // when stream is open
    this.stream.on('open', function () {
      // check that no previous error was given
      if (self.error) {
        var time = new Date();
        self.write('=== ! An error occured in the monitor ! ===');
        self.write('Time: ' + time.toString());
        self.write(self.error);
        self.write(' === error message end ===');
      }

      // we can spawn the process
      self.ready();
    });

    // handle events: process, daemon, monitor
    var messages = {
      daemon : {
        start: ' === daemon started for first time ===',
        restart: '=== ! daemon restarted ! ==='
      },
      monitor: {
        start: '=== monitor started for first time ===',
        restart: '=== ! monitor restarted ! ==='
      },
      process: {
        start: '=== process stated for first time ===',
        restart: '=== ! process restarted ! ===',
        stop: '=== ! process terminated ! ==='
      }
    };

    // will write the message given in the message object and
    // write the current time and date.
    var handle = function (name) {
      return function (state) {
        var time = new Date();
        self.write(messages[name][state]);
        self.write('=== Time: ' + time.toString());
      };
    };

    this.on('daemon', handle('daemon'));
    this.on('monitor', handle('monitor'));
    this.on('process', handle('process'));
  }
  util.inherits(Monitor, immortal.MonitorAbstract);
  exports.Monitor = Monitor;

  // check monitor options
  var exists = fs.exists || path.exists;
  exports.check = function (options, callback) {

    if (typeof options.output !== 'string') {
      callback(new Error('monitor option .output must be a string'));
      return;
    }

    // resolve filepath
    options.output = path.resolve(options.output);

    // se if dirname(output) folder exists
    exists(path.dirname(options.output), function (exist) {
      if (exist === false) {
        callback(new Error('the file path given by monitor option .output do not exist'));
        return;
      }
      callback(null);
    });
  };

})();

@@ -440,32 +440,377 @@
 tions.output);%0A%0A
+    // on windows we will convert %5Cn to %5Cr%5Cn%0A%09  if (process.platform === 'win32') %7B%0A      console.log('createing linebreak parser');%0A      var write = this.stream.write;%0A      this.stream.write = function () %7B%0A        arguments%5B0%5D = arguments%5B0%5D.toString().replace(/%5Cr?%5Cn/g, '%5Cr%5Cn');%0A        return write.apply(this, arguments);%0A      %7D;%0A    %7D%0A%0A
     // stdout an
@@ -1011,126 +1011,8 @@
 );%0A%0A
-    // create a write wrapper method%0A    this.write = function (text) %7B%0A      self.stream.write(text + '%5Cn');%0A    %7D;%0A%0A
     
@@ -2489,16 +2489,130 @@
 nitor;%0A%0A
+  // write to output file%0A  Monitor.prototype.write = function (text) %7B%0A    this.stream.write(text + '%5Cn');%0A  %7D;%0A%0A
   // che

monitor do now convert LF to CR+LF