Evader.addBreach = function(text, isLink, cmdstring) {
  var $bl = $('.breaches_list');
  if(isLink) {
    $bl.append('<li><a href="#">' + text + '</a></li>');
    $bl.find('a:last').attr('data-cmd', cmdstring);
    if(text.match(/Successful/)) {
      Evader.breaches += 1;
    }
    $('.breaches .breach_count').html(Evader.breaches);
  } else {
    $bl.append('<li>' + text + '</li>');
  }
  if(Evader.breaches > 1) {
    var scrollHeight = $bl.prop('scrollHeight');
    if(scrollHeight > 0) {
      $bl.scrollTop(scrollHeight);
    }
  }  
};

Evader.getBreach = function(cmdstring, randseed, result, callback) {
  $.get('/exploit_outcome', {cmd: cmdstring}, function(name) {
    if(randseed && !cmdstring.match(/randseed/)) {
      cmdstring = cmdstring + ' --randseed=' + randseed[1];        
    }
    Evader.addBreach(result + ' (' + name + ') after ' + Evader.counter + ' seconds.', true, cmdstring);
    if(callback) {
      callback();
    }
  });
};

Evader.evaluateLog = function(data) {
  var breaches = data.match(/\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\s+INFO\s*(<br>)?\s*Success\.[\S\s]*?<br>([\S\s]*?)<br>(Info: Using random seed ([^\<]+)\<br\>)?/mg),
      log = $('.log').html(),
      inMongbatMode = log.match(/mongbat/),
      cmd,
      cmdstring,
      randseed,
      error;

  if(data.match(/Running exploit with command/)) {
    Evader.addBreach('Started evader.');
  }

  if(breaches) {
    for(var i = 0; i < breaches.length; i += 1) {
      (function() {
        randseed = breaches[i].match(/Using random seed ([^\<]+)\<br\>/);
        cmd = breaches[i].split('--');
        cmd.shift();
        if(cmd.length) {
          cmd[cmd.length - 1] = cmd[cmd.length - 1].split('<br>')[0];
          cmdstring = '';
          for(var j = 0; j < cmd.length; j += 1) {
            if(!cmd[j].match(/src_port/) && !cmd[j].match(/autoclose/)) {
              cmdstring = cmdstring + '--' + cmd[j];
            }
          }
          cmdstring = './evader ' + cmdstring;
          Evader.getBreach(cmdstring, randseed, 'Successful attack');
        }
      })();
    }
  }
  
  if(inMongbatMode) {
    error = data.match(/\>1\d\d\:([^\<]+)\<br\>/);
    if(error) {
      Evader.addBreach(error[1]);
    }
  }

  if(data.match(/Finished/) || data.match(/Exploit succeeded/)) {
    clearInterval(Evader.refreshId);
    $('input[type=submit].execute').val('EXECUTE');
    if(!inMongbatMode) {
      var result;
      cmdstring = log.match(/Info: Running exploit with command \"([\s\S]+?)\"\s*\<br\>/)[1];
      randseed = log.match(/Using random seed ([^\<]+)\<br\>/);
      if((log.match(/[Ff]ailed/) || log.match(/Error\:/)) && !log.match(/Exploit succeeded/)) {
        error = log.match(/\>\d{3}\:([^\.]+\.)/);
        if(error) { error = error[1]; }
        result = 'Failed attack with error: ' + error;
      } else {
        result = 'Successful attack';
      }
      Evader.getBreach(cmdstring, randseed, result, function() {
        Evader.addBreach('Attack finished.');
      });
    } else {
      Evader.addBreach('Attack finished.');
    }
  }
};

Evader.count = function() {
  Evader.counter += 1;
  $('.breaches .duration').html(Evader.counter + ' SEC');
};

Evader.reset = function() {
  clearInterval(Evader.refreshId);
  Evader.refreshId = null;
  Evader.counter = 0;
  Evader.breaches = 0;
  $('.breaches .breach_count').html(Evader.breaches);
  $('.breaches .duration').html(Evader.counter + ' SEC');
  $('.breaches_list').html('').scrollTop(0);
  $('.log').html('');
};


Evader.startLogging = function() {
  Evader.reset();

  Evader.refreshId = setInterval(function() {
    Evader.count();

    var currentTime = new Date().getTime();

    $.get('/log?session_id=' + Evader.sessionId + '&random=' + currentTime, function(data) {
      if(data.length > 0) {
        var $log = $('.log');
        $log.append(data);
        Evader.evaluateLog(data);
        var scrollHeight = $log.prop('scrollHeight');
        if(scrollHeight > 0) {
          $log.scrollTop(scrollHeight);
        }
      }
    });
  }, 1000);
};


$(function() {
  $('.breaches .breaches_list a:not(.open_log)').live('click', function() {
    var $link = $(this);
    window.CloseShell(function() {
      setTimeout(function() {        
        $.get('/exploit/stop', function() {          
          $.ajax({
            type: 'POST',
            url: '/exploit/run',
            data: {cmd: $link.attr('data-cmd')}
          });

          Evader.startLogging();
        });        
      }, 1000);
    });
  });
  
  $('.open_log').live('click', function() {
    $('input[value="LOG"]').click();
  });
});