import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, act } from "@testing-library/react";
import * as configApi from "../../api/config";
import { useFilterConfig } from "../useFilterConfig";

vi.mock("../../api/config");

describe("useFilterConfig", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(configApi.fetchParsedFilter).mockResolvedValue({
      name: "sshd",
      filename: "sshd.conf",
      source_file: "/etc/fail2ban/filter.d/sshd.conf",
      active: false,
      used_by_jails: [],
      before: null,
      after: null,
      variables: {},
      prefregex: null,
      failregex: [],
      ignoreregex: [],
      maxlines: null,
      datepattern: null,
      journalmatch: null,
      has_local_override: false,
    });
    vi.mocked(configApi.updateParsedFilter).mockResolvedValue(undefined);
  });

  it("calls fetchParsedFilter only once for stable name", async () => {
    const { rerender } = renderHook(
      ({ name }) => useFilterConfig(name),
      { initialProps: { name: "sshd" } },
    );

    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });

    expect(configApi.fetchParsedFilter).toHaveBeenCalledTimes(1);

    rerender({ name: "sshd" });

    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });

    expect(configApi.fetchParsedFilter).toHaveBeenCalledTimes(1);
  });

  it("calls fetchParsedFilter again when name changes", async () => {
    const { rerender } = renderHook(
      ({ name }) => useFilterConfig(name),
      { initialProps: { name: "sshd" } },
    );

    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });

    expect(configApi.fetchParsedFilter).toHaveBeenCalledTimes(1);

    rerender({ name: "apache-auth" });

    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });

    expect(configApi.fetchParsedFilter).toHaveBeenCalledTimes(2);
  });
});
