// src/lib/log-file.ts
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
// Licensed under the Apache License, Version 2.0

import fs from "node:fs";
import path from "node:path";

import numeral from "numeral";

import { Writable, WritableOptions } from "stream";

type StreamCallback = (error?: Error | null) => void;

export interface GadgetLogFileOptions extends WritableOptions {
  basePath: string;
  name: string;
  maxWritesPerFile: number;
  maxFiles: number;
}

export class GadgetLogFile extends Writable {
  options: GadgetLogFileOptions;
  file?: fs.WriteStream;

  fileIdx: number = 0;
  writeCount: number = 0;

  constructor(options: GadgetLogFileOptions) {
    super(options);
    this.options = options;
  }

  open(): void {
    fs.mkdirSync(this.options.basePath, { recursive: true });
    const filename = path.join(
      this.options.basePath,
      `${this.options.name}.${numeral(this.fileIdx).format("000")}.log`,
    );
    this.file = fs.createWriteStream(filename, { encoding: "utf-8" });
    this.writeCount = 0;
  }

  _write(
    chunk: unknown,
    encoding: BufferEncoding,
    callback: StreamCallback,
  ): boolean {
    if (!this.file) {
      return false;
    }
    if (this.writeCount > this.options.maxWritesPerFile) {
      this.file.close();
      if (++this.fileIdx > this.options.maxFiles) {
        this.fileIdx = 0;
      }
      this.open();
    }
    return this.file.write(chunk, encoding, callback);
  }
}
