# frozen_string_literal: true

# Se encarga de guardar los cambios en los archivos y mantenerlos
# actualizados en git
Site::Writer = Struct.new(:site, :file, :content, keyword_init: true) do
  # Realiza la escritura del archivo.
  #
  # **IMPORTANTE:** Usar rutas absolutas siempre y nunca confiar en una
  # ruta que venga de la Internet.
  #
  # TODO: Usar rutas relativas al sitio y sanitizar.
  #
  # TODO: si el archivo está bloqueado, esperar al desbloqueo.  Realizar
  # asincrónicamente?
  def save
    mkdir_p

    File.open(file, File::RDWR | File::CREAT, 0o640) do |f|
      # Bloquear el archivo para que no sea accedido por otro
      # proceso u otre editore
      f.flock(File::LOCK_EX)

      # Empezar por el principio
      f.rewind

      # Escribir el contenido
      f.write(content)

      # Eliminar el resto
      f.flush
      f.truncate(f.pos)
    end.zero?
  end

  # Devuelve la ruta relativa a la raíz del sitio
  def relative_file
    Pathname.new(file).relative_path_from(Pathname.new(site.path)).to_s
  end

  def dirname
    File.dirname file
  end

  def mkdir_p
    FileUtils.mkdir_p dirname
  end
end