'use strict';

var atob = require('atob');

module.exports = function(db) {
  var module = {};
  module.deviceIds = ['CENSIS-LoRa-1','CENSIS-LoRa-2','CENSIS-LoRa-3','CENSIS-LoRa-4','HIE-mobile-1','HIE-demo','HIE-mobile-2','HIE-smart-campus-1','HIE-smart-campus-2','HIE-smart-campus-3','HIE-smart-campus-4','HIE-smart-campus-5','HIE-smart-campus-6','HIE-smart-campus-7','HIE-mDot-1'];

  module.doBulkInsert = function(bulkData) {
    return new Promise(function(resolve, reject) {
      db.tx(function(t) {
        // t = this;
        // creating a sequence of transaction queries:

        // returning a promise that determines a successful transaction:
        return this.batch(bulkData); // all of the queries are to be resolved;
      })
        .then(function(data) {
          return resolve(data);
        })
        .catch(function(error) {
          return reject(error);
        });
    });
  };


  module.sqlInsertRawEvent = function(data) {
    let _data = data;
    console.log('sqlInsertRawEvent');
    return new Promise(function(resolve, reject) {
      db.func('insert_raw',
        [_data.timestamp, _data.event])
        .then(()=> {
          return resolve('ok');
        })
        .catch((err)=> {
          console.error(err);
          return reject(err);
        });
    });
  };

  module.sqlInsertDecoded = function(data) {
    let _data = data;
    return new Promise(function(resolve, reject) {
      db.func('insert_decoded',
        [_data.deviceid, _data.timestamp, _data.lux, _data.co2, _data.temp, _data.humidity, _data.sound])
        .then(()=> {
          return resolve('ok');
        })
        .catch((err)=> {
          console.error(err);
          return reject(err);
        });
    });

  };

  module.genRawQuery = function(data) {
    const timestamp = new Date(data.timestamp['$date']);
    return db.func('insert_raw', [timestamp, data.device_type, data.device_id, data.evt_type, data.evt]);
  };

  module.addNewEvent = function(data) {
    console.log('addNewEvent');
    var self = this;
    return new Promise((resolve, reject) => {

      let _data = {};
      _data.timestamp = new Date();
      _data.event = data;

      self.sqlInsertRawEvent(_data)
                .then((d)=> {
                  console.log('Postgres returns', d);
                  return resolve({reply: 'raw event inserted'});
                })
                .catch((err)=> {
                  console.error(err);
                  return reject(err);
                });
    });
  };

  module.addProcessedEvent = function(data) {
   // console.log('addProcessedEvent');
    var self = this;
    return new Promise((resolve, reject) => {

      let _data = self.rawBreaker(data);

      self.sqlInsertDecoded(_data)
                .then((d)=> {
                //  console.log('Postgres returns', d);
                  return resolve({reply: 'Processed event inserted',data:_data});
                })
                .catch((err)=> {
                  console.error(err);
                  return reject(err);
                });


    });

  };

  module.decoder = function(data) {
    var _obj = {};
    var _data = atob(data).split('');

    var bytes = _data.map(i => i.charCodeAt());

    _obj.light =  parseInt('0x' + ('0' + bytes[0]).substr(-2) + ('0' + bytes[1]).substr(-2));
    _obj.co2 = parseInt(_data[2] + _data[3] + _data[4] + _data[5] + _data[6], 10);
    _obj.temp = (parseInt(_data[7] + _data[8] + _data[9] + _data[10] + _data[11], 10) - 1000) / 10;
    _obj.humid = (parseInt(_data[12] + _data[13] + _data[14] + _data[15] + _data[16], 10) / 10);
    _obj.noise = parseInt('0x' + ('0' + bytes[17]).substr(-2) + ('0' + bytes[18]).substr(-2));
    _obj.binData = bytes;
   // console.log(_obj);
    return _obj;
  };

  module.rawBreaker = function(data) {
    var self = this;
    var workObj = {};

    var device_name = data.topic.split('/')[4];
  //  console.log('Device_name', device_name);
    workObj.deviceid = self.deviceIds.indexOf(device_name);

    if (data.hasOwnProperty('data')) {

      var _data = self.decoder(data.data);

      workObj.lux = _data.light;
      workObj.co2 = _data.co2;
      workObj.temp = _data.temp;
      workObj.humidity = _data.humid;
      workObj.sound = _data.noise;
      workObj.timestamp = new Date();

      return workObj;
    } else {
      console.error('Data does not have base64 data');

      return null;
    }

  };

  return module;
};