lib/downloader.ex

defmodule ActiveStorage.Downloader do
  # attr_reader :service
  alias __MODULE__
  defstruct [:service]

  def new(service) do
    %__MODULE__{service: service}
    # @service = service
  end

  # def open(key, %{checksum: checksum, verify: verify, name: name, tmpdir: tmpdir}) do
  def open(downloader, key, args, block) do
    a = downloader.service.download(key)

    dir = System.tmp_dir!()
    tmp_file = Path.join(dir, args.name)
    IO.inspect(tmp_file)

    {:ok, _file} =
      open_tempfile(tmp_file, fn file ->
        verify_integrity_of(a, args)
        IO.binwrite(file, a)
        File.close(file)
      end)

    block.(tmp_file)

    # IO.binwrite(file, a)
    # File.close(file)

    # File.write!(tmp_file)

    # open_tempfile(name, tmpdir) do |file|
    #  download key, file
    #  verify_integrity_of(file, checksum: checksum) if verify
    #  yield file
    # end
  end

  defp open_tempfile(tmp_file, block) do
    # File.open(tmp_file, [:write])
    File.open(tmp_file, [:read, :write], block)

    # file = Tempfile.open(name, tmpdir)

    # begin
    #  yield file
    # ensure
    #  file.close!
    # end
  end

  defp download(_service, _key, _file) do
    # file.binmode
    # service.download(key) { |chunk| file.write(chunk) }
    # file.flush
    # file.rewind
  end

  defp verify_integrity_of(file, %{checksum: checksum}) do
    case :crypto.hash(:md5, file) |> Base.encode64() == checksum do
      true -> true
      false -> raise "ActiveStorage::IntegrityError"
    end

    # unless OpenSSL::Digest::MD5.file(file).base64digest == checksum
    #   raise ActiveStorage::IntegrityError
    # end
  end
end