import { readFile } from "node:fs/promises";
import { z } from "zod";

const clientSchema = z.object({
  ipAddress: z.string().max(64),
  macAddress: z.string().max(32),
  hostname: z.string().max(128).nullable(),
  leaseExpiresAt: z.string().nullable(),
  state: z.string().max(32),
  connected: z.boolean()
});

const dnsQuerySchema = z.object({
  timestamp: z.string(),
  clientAddress: z.string().max(64),
  type: z.string().max(16),
  name: z.string().max(253)
});

const flowSchema = z.object({
  protocol: z.enum(["tcp", "udp"]),
  state: z.string().max(32),
  sourceAddress: z.string().max(64),
  sourcePort: z.number().int().min(0).max(65_535),
  destinationAddress: z.string().max(64),
  destinationPort: z.number().int().min(0).max(65_535),
  packets: z.number().int().nonnegative().nullable(),
  bytes: z.number().int().nonnegative().nullable()
});

export const networkActivitySchema = z.object({
  collectedAt: z.string(),
  clients: z.array(clientSchema).max(256),
  dnsQueries: z.array(dnsQuerySchema).max(250),
  flows: z.array(flowSchema).max(150),
  dnsAvailable: z.boolean(),
  flowsAvailable: z.boolean(),
  messages: z.array(z.string().max(300)).max(8)
});

export type NetworkActivity = z.infer<typeof networkActivitySchema> & { supported: boolean };

export async function readNetworkActivity(path: string): Promise<NetworkActivity> {
  try {
    return { ...networkActivitySchema.parse(JSON.parse(await readFile(path, "utf8"))), supported: true };
  } catch {
    return {
      supported: false,
      collectedAt: new Date(0).toISOString(),
      clients: [],
      dnsQueries: [],
      flows: [],
      dnsAvailable: false,
      flowsAvailable: false,
      messages: ["Network activity is available after the observer service is installed and started."]
    };
  }
}
