/*
    Script: fetchSystemData.mjs

    Dieses Script lädt sowohl Systemdaten (z.B. Spannungen und Temperaturen) als auch die Messdaten der 8 analogen Eingänge eines CPL-Geräts
    für die letzten 30 Tage per HTTP/HTTPS-API herunter und speichert sie als Mockdaten im lokalen Dateisystem.

    - Systemdaten: Für die Inputs 108 (+15V), 110 (+5V), 114 (-15V), 115 (-98V), 116 (Temperatur AD Wandler), 117 (Temperatur Prozessor)
      werden die Daten für die DIA-Typen DIA0, DIA1, DIA2 jeweils in das Verzeichnis
      mocks/device-cgi-simulator/chartsData/<systemVerzeichnis>/DIAx.json geschrieben.

    - Analoge Eingänge: Für die Eingänge 100 bis 107 werden die Daten für die DIA-Typen DIA0, DIA1, DIA2 jeweils in das Verzeichnis
      mocks/device-cgi-simulator/chartsData/analogInputs/<Eingang-Index>/DIAx.json geschrieben.

    Das Script authentifiziert sich mit Benutzername und Passwort, akzeptiert selbst-signierte Zertifikate und kann für Tests und Simulationen
    verwendet werden, um die Mockdaten aktuell zu halten.

    Ausführung: node fetchSystemData.mjs
*/

import fetch from "node-fetch";
import https from "https";
import fs from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));

// Host/IP des CPL-Geräts
const CPL_HOST = "https://10.10.0.118";
// Zugangsdaten für die Authentifizierung
const USERNAME = "Littwin";
const PASSWORD = "Littwin";
// Verfügbare DIA-Typen
const DIA_TYPES = ["DIA0", "DIA1", "DIA2"];
// Systemdaten: Input-Nummer und Zielverzeichnis
const SYSTEM_INPUTS = [
  { input: 108, dir: "systemspannung15Vplus" },
  { input: 110, dir: "systemspannung5Vplus" },
  { input: 114, dir: "systemspannung15Vminus" },
  { input: 115, dir: "systemspannung98Vminus" },
  { input: 116, dir: "temperaturADWandler" },
  { input: 117, dir: "temperaturProzessor" },
];
// Analoge Eingänge: Nummern 100 bis 107
const ANALOG_INPUTS = Array.from({ length: 8 }, (_, i) => 100 + i); // 100-107

// Hilfsfunktion zum Formatieren des Datums (YYYY-MM-DD)
function formatDate(date) {
  return date.toISOString().slice(0, 10);
}
// Aktuelles Datum und 30 Tage zurück
const today = new Date();
const TO_DATE = formatDate(today);
const fromDateObj = new Date(today);
fromDateObj.setDate(today.getDate() - 30);
const FROM_DATE = formatDate(fromDateObj);

// Hilfsfunktion für Datumssplittung
function getDateParts() {
  const [vonJahr, vonMonat, vonTag] = FROM_DATE.split("-");
  const [bisJahr, bisMonat, bisTag] = TO_DATE.split("-");
  return { vonJahr, vonMonat, vonTag, bisJahr, bisMonat, bisTag };
}

// URL für Systemdaten generieren
function getSystemUrl(dia, input) {
  const { vonJahr, vonMonat, vonTag, bisJahr, bisMonat, bisTag } =
    getDateParts();
  return `${CPL_HOST}/CPL?seite.ACP&${dia}=${vonJahr};${vonMonat};${vonTag};${bisJahr};${bisMonat};${bisTag};${input};1;`;
}

// URL für analoge Eingänge generieren
function getAnalogUrl(dia, eingang) {
  const { vonJahr, vonMonat, vonTag, bisJahr, bisMonat, bisTag } =
    getDateParts();
  return `${CPL_HOST}/CPL?seite.ACP&${dia}=${vonJahr};${vonMonat};${vonTag};${bisJahr};${bisMonat};${bisTag};${eingang};1`;
}

// Holt und speichert die Systemdaten für einen DIA-Typ und Input im Zielverzeichnis
async function fetchAndSaveSystem(dia, input, dir) {
  const url = getSystemUrl(dia, input);
  console.log(`Fetch Systemdaten: ${dir} ${dia} ->`, url);
  const agent = new https.Agent({ rejectUnauthorized: false });
  const res = await fetch(url, {
    headers: {
      Authorization:
        "Basic " + Buffer.from(`${USERNAME}:${PASSWORD}`).toString("base64"),
    },
    agent,
  });
  if (!res.ok) throw new Error(`Fehler bei ${dia} (${input}): ${res.status}`);
  const data = await res.json();
  const targetDir = path.join(
    __dirname,
    `../device-cgi-simulator/chartsData/${dir}`
  );
  await fs.mkdir(targetDir, { recursive: true });
  await fs.writeFile(
    path.join(targetDir, `${dia}.json`),
    JSON.stringify(data, null, 2)
  );
}

// Holt und speichert die Daten für einen analogen Eingang und DIA-Typ im Zielverzeichnis
async function fetchAndSaveAnalog(dia, eingang) {
  const url = getAnalogUrl(dia, eingang);
  console.log(`Fetch Analogeingang ${eingang} ${dia} ->`, url);
  const agent = new https.Agent({ rejectUnauthorized: false });
  const res = await fetch(url, {
    headers: {
      Authorization:
        "Basic " + Buffer.from(`${USERNAME}:${PASSWORD}`).toString("base64"),
    },
    agent,
  });
  if (!res.ok)
    throw new Error(`Fehler bei Eingang ${eingang} ${dia}: ${res.status}`);
  const data = await res.json();
  const dir = path.join(
    __dirname,
    "../device-cgi-simulator/chartsData/analogInputs",
    String(eingang - 99)
  );
  await fs.mkdir(dir, { recursive: true });
  await fs.writeFile(
    path.join(dir, `${dia}.json`),
    JSON.stringify(data, null, 2)
  );
}

// Hauptfunktion: Lädt alle Systemdaten und analoge Eingänge und speichert sie als Mockdaten
(async () => {
  // Systemdaten abrufen und speichern
  for (const { input, dir } of SYSTEM_INPUTS) {
    for (const dia of DIA_TYPES) {
      try {
        await fetchAndSaveSystem(dia, input, dir);
      } catch (e) {
        console.error(e);
      }
    }
  }

  // Analoge Eingänge abrufen und speichern
  for (const eingang of ANALOG_INPUTS) {
    for (const dia of DIA_TYPES) {
      try {
        await fetchAndSaveAnalog(dia, eingang);
      } catch (e) {
        console.error(e);
      }
    }
  }
  console.log("Alle Systemdaten und Analoge Eingänge Mockdaten aktualisiert.");
})();
