# frozen_string_literal: true

class HandleChunkUpload

  def initialize(chunk, params = {})
    @chunk = chunk
    @params = params
  end

  def self.check_chunk(chunk, params)
    HandleChunkUpload.new(chunk, params).check_chunk
  end

  def self.upload_chunk(chunk, params)
    HandleChunkUpload.new(chunk, params).upload_chunk
  end

  def self.merge_chunks(chunk, params)
    HandleChunkUpload.new(chunk, params).merge_chunks
  end

  def check_chunk
    # check whether the chunk has already been uploaded
    has_chunk_been_uploaded = File.exists?(@chunk) && File.size(@chunk) == @params[:current_chunk_size]
    # 200 = exists, 404 = not uploaded yet
    status = has_chunk_been_uploaded ? 200 : 404
  end

  def upload_chunk
    # path to chunk file
    dir = File.dirname(@chunk)
    # ensure directory exists
    FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
    # save chunk to the directory
    File.open(@chunk, "wb") { |f| f.write(@params[:file].tempfile.read) }
  end

  def merge_chunks
    upload_path     = @params[:upload_path]
    tmp_upload_path = @params[:tmp_upload_path]
    identifier      = @params[:identifier]
    filename        = @params[:filename]
    tmp_directory   = @params[:tmp_directory]

    # delete destination files
    begin
      File.delete(upload_path)
      File.delete(tmp_upload_path)
    rescue Errno::ENOENT
    end

    # merge all the chunks
    File.open(tmp_upload_path, "a") do |file|
      (1..@chunk).each do |chunk_number|
        # path to chunk
        chunk_path = BackupRestore::LocalBackupStore.chunk_path(identifier, filename, chunk_number)
        # add chunk to file
        file << File.open(chunk_path).read
      end
    end

    # rename tmp file to final file name
    FileUtils.mv(tmp_upload_path, upload_path, force: true)

    # remove tmp directory
    begin
      FileUtils.rm_rf(tmp_directory)
    rescue Errno::ENOENT
    end
  end

end
