#include "mocks.h" // Plik z mockami, który stworzyliśmy w poprzednim kroku
#include "ZDistA_komp.c"

// Globalne instancje struktur dla pojedynczego kanału testowego
static struct ZDistA_komp_args args;
static struct ZDistA_komp_logic log_inst;

// Zmienne do trzymania wejść
static float i1_re, i1_im, i1_mod;
static float i2_re, i2_im, i2_mod;
static float i3_re, i3_im, i3_mod;
static float i0_re, i0_im, i0_mod;
static float i1_zg_re, i1_zg_im, i1_zg_mod; // Składowa zgodna I1
static float i2_pr_re, i2_pr_im, i2_pr_mod; // Składowa przeciwna I2

static float u1_re, u1_im, u1_mod;
static float u2_re, u2_im, u2_mod;
static float u3_re, u3_im, u3_mod;
static float u0_re, u0_im, u0_mod;

static struct binary_io out_P1W_L1E, out_P1W_L2E, out_P1W_L3E;

// Funkcja eksportowana dla Pythona do inicjalizacji
__declspec(dllexport) void init_relay()
{
    memset(&args, 0, sizeof(args));
    memset(&log_inst, 0, sizeof(log_inst));

    // Podpięcie wskaźników (tylko przykład dla I1 i wyjść)
    args.io.i1_orta_float_in = &i1_re;
    args.io.i1_ortb_float_in = &i1_im;
    args.io.i1_float_in = &i1_mod;

    // ... tu musisz podpiąć resztę wskaźników dla U1, U2, I0, I2_pr itd.

    args.io.P1W_L1E_out = &out_P1W_L1E;
    args.io.P1W_L2E_out = &out_P1W_L2E;
    args.io.P1W_L3E_out = &out_P1W_L3E;

    // Ustawienie bazowych nastaw
    args.params.bity = 0xFFFF; // Włącz wszystko do testu
    args.params.kp = 1.0;
    args.params.fi1 = 75.0; // Kąt charakterystyki
    args.params.R1_Zf1_LE = 10.0;
    args.params.X1_Zr1_LE = 20.0;

    ZDistA_komp_initlog(&args, &log_inst);
}

// Funkcja eksportowana dla Pythona do pojedynczego kroku obliczeń
__declspec(dllexport) void step_relay(
    float i1re, float i1im, float u1re, float u1im,
    float i0re, float i0im, float u0re, float u0im,
    float i2pr_re, float i2pr_im, float i1zg_re, float i1zg_im,
    int *trip_L1, int *trip_L2, int *trip_L3)
{
    // 1. Przepisanie wejść z Pythona
    i1_re = i1re;
    i1_im = i1im;
    u1_re = u1re;
    u1_im = u1im;
    i0_re = i0re;
    i0_im = i0im;

    // Obliczenie modułów (algorytm ich wymaga)
    i1_mod = sqrtf(i1_re * i1_re + i1_im * i1_im);
    u1_mod = sqrtf(u1_re * u1_re + u1_im * u1_im);

    // Zasilenie składowych symetrycznych
    i2_pr_re = i2pr_re;
    i2_pr_im = i2pr_im;
    i1_zg_re = i1zg_re;
    i1_zg_im = i1zg_im;

    // 2. Wykonanie algorytmu zabezpieczeniowego
    ZDistA_komp(&args, &log_inst);

    // 3. Zebranie wyników i przekazanie z powrotem do Pythona
    *trip_L1 = check_struct(log_inst.P1W_L1E);
    *trip_L2 = check_struct(log_inst.P1W_L2E);
    *trip_L3 = check_struct(log_inst.P1W_L3E);
}
