/**
 * React hook for loading and updating a single parsed jail.d config file.
 */

import { useCallback } from "react";
import { useConfigItem } from "./useConfigItem";
import { fetchParsedJailFile, updateParsedJailFile } from "../api/config";
import type { JailFileConfig, JailFileConfigUpdate } from "../types/config";

export interface UseJailFileConfigResult {
  config: JailFileConfig | null;
  loading: boolean;
  error: string | null;
  refresh: () => void;
  save: (update: JailFileConfigUpdate) => Promise<void>;
}

/**
 * Load one jail.d config file by filename and expose a ``save`` callback for
 * partial updates.
 *
 * @param filename - Filename including extension (e.g. ``"sshd.conf"``).
 */
export function useJailFileConfig(filename: string): UseJailFileConfigResult {
  const fetchFn = useCallback(
    (signal: AbortSignal) => fetchParsedJailFile(filename, signal),
    [filename],
  );
  const saveFn = useCallback(
    (update: JailFileConfigUpdate) => updateParsedJailFile(filename, update),
    [filename],
  );

  const { data, loading, error, refresh, save } = useConfigItem<
    JailFileConfig,
    JailFileConfigUpdate
  >({
    fetchFn,
    saveFn,
    mergeOnSave: (prev, update) =>
      update.jails != null && prev
        ? { ...prev, jails: { ...prev.jails, ...update.jails } }
        : prev,
  });

  return {
    config: data,
    loading,
    error,
    refresh,
    save,
  };
}
