import * as plugins from '../plugins.js';
import type { IConfigStore } from './types.js';

export class JsonFileConfigStore implements IConfigStore {
  constructor(private readonly filePath: string) {}

  public async get<TValue>(keyArg: string): Promise<TValue | undefined> {
    const data = await this.readFile();
    return data[keyArg] as TValue | undefined;
  }

  public async set<TValue>(keyArg: string, valueArg: TValue): Promise<void> {
    const data = await this.readFile();
    data[keyArg] = valueArg;
    await this.writeFile(data);
  }

  public async delete(keyArg: string): Promise<void> {
    const data = await this.readFile();
    delete data[keyArg];
    await this.writeFile(data);
  }

  public async list(prefixArg = ''): Promise<string[]> {
    const data = await this.readFile();
    return Object.keys(data).filter((keyArg) => keyArg.startsWith(prefixArg));
  }

  private async readFile(): Promise<Record<string, unknown>> {
    try {
      const fileString = await plugins.fs.readFile(this.filePath, 'utf8');
      return JSON.parse(fileString) as Record<string, unknown>;
    } catch (error) {
      return {};
    }
  }

  private async writeFile(dataArg: Record<string, unknown>): Promise<void> {
    await plugins.fs.mkdir(plugins.path.dirname(this.filePath), { recursive: true });
    await plugins.fs.writeFile(this.filePath, `${JSON.stringify(dataArg, null, 2)}\n`);
  }
}
