/*    Copyright 2016 Firewalla LLC 
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict'

let firewalla = require('./Firewalla.js');

let BitBridge = require('../extension/bitbridge/bitbridge.js')

var spawn = require('child_process').spawn;

let spawnProcess = null;

let spoofLogFile = firewalla.getLogFolder() + "/spoof.log";

let SysManager = require("./SysManager.js");
let sysManager = new SysManager();

let Promise = require('bluebird');

const async = require('asyncawait/async')
const await = require('asyncawait/await')

let redis = require('redis');
let rclient = redis.createClient();

let log = require("./logger.js")(__filename, 'info');

let fs = require('fs');

let cp = require('child_process');

let monitoredKey = "monitored_hosts";
let unmonitoredKey = "unmonitored_hosts";

let spoofStarted = false;

// add promises to all redis functions
Promise.promisifyAll(redis.RedisClient.prototype);
Promise.promisifyAll(redis.Multi.prototype);

// WORKAROUND VERSION HERE, will move to a better place
function startSpoofing() {

  if(spoofStarted) {
    return Promise.resolve();
  }
  
  log.info("start spoofing")

  return async(() => {
    // clean up redis key
    
    await (rclient.delAsync(monitoredKey))
    await (rclient.delAsync(unmonitoredKey))

    let ifName = sysManager.monitoringInterface().name;
    let routerIP = sysManager.myGateway();
    let myIP = sysManager.myIp();
    
    if(!ifName || !myIP || !routerIP) {
      return Promise.reject("require valid interface name, ip address and gateway ip address");
    }
    
    let b7 = new BitBridge(ifName, routerIP, myIP)
    b7.start()
    
    spoofStarted = true;
    return Promise.resolve();
  })()
  
}

function stopSpoofing() {
  return new Promise((resolve, reject) => {
    spoofStarted = false;
    
    let ifName = sysManager.monitoringInterface().name;
    let routerIP = sysManager.myGateway();
    let myIP = sysManager.myIp();

    if(!ifName || !myIP || !routerIP) {
      return Promise.reject("require valid interface name, ip address and gateway ip address");
    }
    
    let b7 = new BitBridge(ifName, routerIP, myIP)
    b7.stop()
      .then(() => {
        resolve()
      })
  }).catch((err) => {
    //catch everything here
    log.error("Failed to stop spoofing:", err, {})
  })
}

module.exports = {
  startSpoofing: startSpoofing,
  stopSpoofing: stopSpoofing
}

@@ -999,24 +999,122 @@
 Manager();%0A%0A
+let HostManager = require('./HostManager.js')%0Alet hostManager = new HostManager('cli', 'server')%0A%0A
 let Promise 
@@ -1482,24 +1482,100 @@
 ed_hosts%22;%0A%0A
+let HostTool = require('../net2/HostTool')%0Alet hostTool = new HostTool();%0A%0A%0A
 let spoofSta
@@ -1928,123 +1928,41 @@
     
-// clean up redis key%0A    %0A    await (rclient.delAsync(monitoredKey))%0A    await (rclient.delAsync(unmonitoredKey))%0A
+await (this.emptySpoofSet())%0A    
 %0A   
@@ -2985,16 +2985,605 @@
   %7D)%0A%7D%0A%0A
+function emptySpoofSet() %7B%0A  return async(() =%3E %7B%0A    // clean up redis key%0A    await (rclient.delAsync(monitoredKey))%0A    await (rclient.delAsync(unmonitoredKey))%0A  %7D)()%0A%7D%0A%0Afunction loadManualSpoofs() %7B%0A  let activeMACs = hostManager.getActiveMACs()%0A%0A  return async(() =%3E %7B%0A    %0A    activeMACs.forEach((mac) =%3E %7B%0A      let key = hostTool.getMacKey(mac)%0A      let host = await (rclient.hgetallAsync(key))%0A      let manualSpoof = (host.manualSpoof === '1' ? true : false)%0A      if(manualSpoof) %7B%0A        await (rclient.saddAsync(monitoredKey, host.ipv4Addr))%0A      %7D%0A    %7D)%0A    %0A  %7D)()%0A%0A%7D%0A%0A
 module.e
@@ -3653,11 +3653,81 @@
 Spoofing
+,%0A  loadManualSpoofs: loadManualSpoofs,%0A  emptySpoofSet: emptySpoofSet
 %0A%7D%0A

add code to load manual spoof info from mac to monitor set