const fs = require('fs').promises;
const {logip} = require('./src/logip');
const {localizate} = require('./src/localization');
const {localizateOriginal} = require('./src/localizateOriginal');
const {sleep} = require('./src/helper');
const {Matrix} = require('ml-matrix');

logip();

function median(values){
  if(values.length ===0) return 0;

  values.sort(function(a,b){
    return a-b;
  });

  var half = Math.floor(values.length / 2);

  if (values.length % 2)
    return values[half];

  return (values[half - 1] + values[half]) / 2.0;
}

function parseHrtimeToSeconds(hrtime) {
  const seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
  return seconds;
}

const save_to_map = true;

const io = require('socket.io')("80");
console.log("start");
const android_poses = [];

function cam_pos_phone(data) {
  // console.log('Cam pos phone', data);
  // console.log('Cam pos phone');
  io.emit("cam_pos_web", data);
}
let it = 0;
let dobre = 0;
let zle = 0;
const pokusy = [];
async function cam_img_phone(data) {
  const startTime = process.hrtime();

  // console.log('Cam img phone', data);
  // console.log('Cam img phone');
  if (data.image == null) return;
  if(false){
    // const filename = './input/10/' + data.name + ".jpeg";
    // await fs.writeFile(filename, data.image, {encoding: 'base64'});
    // console.log('it: ', it);
    // it++;
    // return;
  }
  io.emit("cam_img_web", data);
  // const filename = './camera_images/6/' + data.name + ".jpeg";
  const filename = './imgs/' + data.name + ".jpeg";
  await fs.writeFile(filename, data.image, {encoding: 'base64'});
  const out = await localizate(filename, data.name + ".jpeg");
  if (!out){
    zle++;
    return;
  }
  // const res = {...out, hashCode: data.hashCode + "010101"};
  // const res = {...out, hashCode: data.hashCode};
  // console.log('res', res);
  // io.emit("cam_pos_web", res);
  const localization_data = {};
  // to column major
  const matrixColumn = Matrix.from1DArray(4, 4, out.matrix.flat()).transpose().to1DArray();
  localization_data.matrix = matrixColumn;
  localization_data.hashCode = data.hashCode;
  localization_data.requestId = data.requestId;
  localization_data.androidPoses = android_poses;
  dobre++;
  io.emit("localization_data", localization_data);
  const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
  pokusy.push(elapsedSeconds);
  console.log('It takes ' + elapsedSeconds + 'seconds');
  console.log("dobre: ", dobre, " zle: ", zle, " it: ", it);
  console.log("pokusy median: ", median(pokusy));
}

function cam_pointcloud_phone(data) {
  console.log('Cam pointcloud phone', data);
  io.emit("cam_pointcloud_web", data);
  console.log('poslane pointcloud');
}

function add_android(data){
  console.log('add android', data);
  android_poses.push(data.matrix);
  io.emit("add_android", data);
}

io.on('connection', function (socket) {
  io.emit('this', {will: 'be received by everyone'});
  socket.on('cam_pos_phone', cam_pos_phone);
  socket.on('add_android', add_android);
  socket.on('cam_img_phone', cam_img_phone);
  socket.on('cam_pointcloud_phone', cam_pointcloud_phone);
  socket.on('disconnect', function () {
    io.emit('user disconnected');
  });
  socket.on('error', function (err) {
    console.error(err, "123123123");
  })
});

async function test(name){
  const data = {};
  data.name = name;
  console.log('start test');
  const filename = './imgs/' + data.name + ".jpeg";
  const out = await localizate(filename, data.name + ".jpeg");
  const res = {...out, hashCode: "filecamera"};
  console.log('res', res);
  // const out = localizate(commandQ);
  io.emit("cam_pos_web", res);
}
// const name1 = "camera_image2019_04_27_11_08_46_54";
// const name2 = "camera_image2019_04_27_11_08_46_94";
// setInterval(async function(){
  // await test(name1);
  // await sleep(1000);
  // await test(name2);
  // }, 2000);
// test(name1);
// localizate(commandQ);
// localizateOriginal(io);