import { mkdir, readFile, writeFile, unlink, access } from 'fs/promises'
import { dirname, join } from 'path'
import type { StorageProvider } from './provider.js'

export class LocalStorageProvider implements StorageProvider {
  private root: string
  private baseUrl: string

  constructor(root: string, baseUrl: string) {
    this.root = root
    this.baseUrl = baseUrl
  }

  private fullPath(path: string): string {
    return join(this.root, path)
  }

  async put(path: string, data: Buffer, _contentType: string): Promise<void> {
    const fullPath = this.fullPath(path)
    await mkdir(dirname(fullPath), { recursive: true })
    await writeFile(fullPath, data)
  }

  async get(path: string): Promise<Buffer> {
    return readFile(this.fullPath(path))
  }

  async delete(path: string): Promise<void> {
    try {
      await unlink(this.fullPath(path))
    } catch (err: unknown) {
      if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err
    }
  }

  async exists(path: string): Promise<boolean> {
    try {
      await access(this.fullPath(path))
      return true
    } catch {
      return false
    }
  }

  async getUrl(path: string, _expiresIn?: number): Promise<string> {
    return `${this.baseUrl}/v1/files/serve/${encodeURIComponent(path)}`
  }
}
