const axios = require("axios");
const shared = require("./shared.js");
const { Log } = require("./logs.js");
let hostIDs = [];
let monitorInterval;

async function Monitoring() {
  await initHostList();
  Log(`\n[${shared.now()}] Inizio monitoring`);
  //monitora tutti gli host della lista
  shared.eventEmitter.on("tokenRenewalStart", () => {
    clearInterval(monitorInterval);
  });
  shared.eventEmitter.on("tokenRenewalEnd", () => {
    monitorInterval = setInterval(Request, minute - 1);
  });
  monitorInterval = setInterval(Request, minute - 1);
}

async function Request() {
  let hosts = [];
  for (const element of hostIDs) {
    let obj = {
      id: element,
      [element]: await isConnected(element),
    };
    hosts.push(obj);
  }
  shared.setHosts(hosts);
}

async function isConnected(hostID) {
  let loopError;
  let errorCount = 0;
  do {
    try {
      const response = await axios.get(
        `https://api.netbird.io/api/peers/${hostID}`,
        {
          headers: {
            Accept: "application/json",
            Authorization: `Token ${shared.getToken()}`,
          },
        }
      );
      Log(`[${shared.now()}] ${hostID} connected: ${response.data.connected}`);
      return response.data.connected;
    } catch (error) {
      loopError = true;
      Log(
        `[${shared.now()}] Errore nella verifica dello stato per l'host ${hostID}`
      );
      Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
      for (const codice of shared.codiciNonAccettati) {
        if (error.response?.status === codice) {
          Log(
            `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
          );
          Log(
            `[${shared.now()}] Per favore riavviare il programma con un token valido.`
          );
          process.exit(3);
        }
      }
      Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
    }
  } while (loopError);
}

async function initHostList() {
  let loopError;
  let errorCount = 0;
  if ("HOSTNAMES" in process.env) {
    let envHostnames = process.env.HOSTNAMES;

    if (
      envHostnames !== null &&
      envHostnames !== undefined &&
      envHostnames !== ""
    ) {
      if (envHostnames.includes(";")) {
        envHostnames = envHostnames.split(";");

        for (const host of envHostnames) {
          do {
            loopError = false;
            try {
              const response = await axios.get(
                `https://api.netbird.io/api/peers?name=${host}`,
                {
                  headers: {
                    Accept: "application/json",
                    Authorization: `Token ${shared.getToken()}`,
                  },
                }
              );
              for (const host of response.data) {
                hostIDs.push(host.id);
              }
            } catch (error) {
              loopError = true;
              Log(
                `[${shared.now()}] Errore nella verifica e aggiunta al monitoraggio di un host.`
              );
              Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
              for (const codice of shared.codiciNonAccettati) {
                if (error.response?.status === codice) {
                  Log(
                    `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
                  );
                  Log(
                    `[${shared.now()}] Per favore riavviare il programma con un token valido.`
                  );
                  process.exit(3);
                }
              }
              Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
            }
          } while (loopError);
        }
      } else {
        do {
          loopError = false;
          try {
            const response = await axios.get(
              `https://api.netbird.io/api/peers?name=${envHostnames}`,
              {
                headers: {
                  Accept: "application/json",
                  Authorization: `Token ${shared.getToken()}`,
                },
              }
            );
            hostIDs.push(response.data[0].id);
          } catch (error) {
            loopError = true;
            Log(
              `[${shared.now()}] Errore nella verifica e aggiunta al monitoraggio di un host.`
            );
            Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
            for (const codice of shared.codiciNonAccettati) {
              if (error.response?.status === codice) {
                Log(
                  `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
                );
                Log(
                  `[${shared.now()}] Per favore riavviare il programma con un token valido.`
                );
                process.exit(3);
              }
            }
            Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
          }
        } while (loopError);
      }
    }
  } else if ("HOSTIDS" in process.env) {
    let envHostIDs = process.env.HOSTIDS;

    if (envHostIDs !== null && envHostIDs !== undefined && envHostIDs !== "") {
      if (envHostIDs.includes(";")) {
        envHostIDs = envHostIDs.split(";");

        for (const host of envHostIDs) {
          do {
            loopError = false;
            try {
              const response = await axios.get(
                `https://api.netbird.io/api/peers/${host}`,
                {
                  headers: {
                    Accept: "application/json",
                    Authorization: `Token ${shared.getToken()}`,
                  },
                }
              );
              hostIDs.push(response.data.id);
            } catch (error) {
              loopError = true;
              Log(
                `[${shared.now()}] Errore nella verifica e aggiunta al monitoraggio di un host.`
              );
              Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
              for (const codice of shared.codiciNonAccettati) {
                if (error.response?.status === codice) {
                  Log(
                    `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
                  );
                  Log(
                    `[${shared.now()}] Per favore riavviare il programma con un token valido.`
                  );
                  process.exit(3);
                }
              }
              Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
            }
          } while (loopError);
        }
      } else {
        do {
          loopError = false;
          try {
            const response = await axios.get(
              `https://api.netbird.io/api/peers/${envHostIDs}`,
              {
                headers: {
                  Accept: "application/json",
                  Authorization: `Token ${shared.getToken()}`,
                },
              }
            );
            hostIDs.push(response.data.id);
          } catch (error) {
            loopError = true;
            Log(
              `[${shared.now()}] Errore nella verifica e aggiunta al monitoraggio di un host.`
            );
            Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
            for (const codice of shared.codiciNonAccettati) {
              if (error.response?.status === codice) {
                Log(
                  `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
                );
                Log(
                  `[${shared.now()}] Per favore riavviare il programma con un token valido.`
                );
                process.exit(3);
              }
            }
            Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
          }
        } while (loopError);
      }
    }
  } else {
    Log(
      `[${shared.now()}] Nessun peer specificato, verranno monitorati tutti i peer disponibili`
    );
    do {
      loopError = false;
      try {
        const response = await axios.get(`https://api.netbird.io/api/peers`, {
          headers: {
            Accept: "application/json",
            Authorization: `Token ${shared.getToken()}`,
          },
        });

        for (const element of response.data) {
          hostIDs.push(element.id);
        }
      } catch (error) {
        loopError = true;
        Log(`[${shared.now()}] Errore nel tentativo di reperire tutti i peer.`);
        Log(`[${shared.now()}] Codice HTTP ${error.response?.status}`);
        Log(`[${shared.now()}] Debug: ${error}`);
        for (const codice of shared.codiciNonAccettati) {
          if (error.response?.status === codice) {
            Log(
              `[${shared.now()}] Errore grave: il token inserito non esiste, non è valido o è scaduto.`
            );
            Log(
              `[${shared.now()}] Per favore riavviare il programma con un token valido.`
            );
            process.exit(3);
          }
        }
        Log(`[${shared.now()}] Nuovo tentativo n. ${errorCount++}`);
      }
    } while (loopError);
  }

  Log(`[${shared.now()}] ID rilevati:`);
  for (const element of hostIDs) {
    Log(`[${shared.now()}] ${element}`);
  }
}

module.exports = { Monitoring };
