// @ts-nocheck
import axios from "axios";
import { Ping } from "../ping.js";
import {
  UP,
  DOWN,
  DEGRADED,
  REALTIME,
  TIMEOUT,
  ERROR,
  MANUAL,
} from "../constants.js";

const defaultPingEval = `(async function (responseDataBase64) {
	let arrayOfPings = JSON.parse(atob(responseDataBase64));
	let latencyTotal = arrayOfPings.reduce((acc, ping) => {
		return acc + ping.latency;
	}, 0);

	let alive = arrayOfPings.reduce((acc, ping) => {
		return acc && ping.alive;
	}, true);

	return {
		status: alive ? 'UP' : 'DOWN',
		latency: latencyTotal / arrayOfPings.length,
	}
})`;

class PingCall {
  monitor;

  constructor(monitor) {
    this.monitor = monitor;
  }

  async execute() {
    let hosts = this.monitor.type_data.hosts;
    let pingEval = !!this.monitor.type_data.pingEval
      ? this.monitor.type_data.pingEval
      : defaultPingEval;
    let tag = this.monitor.tag;
    if (hosts === undefined) {
      console.log(
        "Hosts is undefined. The ping monitor has changed in version 3.0.10. Please update your monitor with tag",
        tag,
      );
      return {
        status: DOWN,
        latency: 0,
        type: ERROR,
      };
    }
    let arrayOfPings = [];
    for (let i = 0; i < hosts.length; i++) {
      const host = hosts[i];
      arrayOfPings.push(
        await Ping(host.type, host.host, host.timeout, host.count),
      );
    }
    let respBase64 = Buffer.from(JSON.stringify(arrayOfPings)).toString(
      "base64",
    );

    let evalResp = undefined;

    try {
      evalResp = await eval(pingEval + `("${respBase64}")`);
    } catch (error) {
      console.log(`Error in pingEval for ${tag}`, error.message);
    }
    //reduce to get the status
    return {
      status: evalResp.status,
      latency: evalResp.latency,
      type: REALTIME,
    };
  }
}

export default PingCall;
