module WolfCore::FileUtils

def base64_string_to_bytes(base64_string)

def base64_string_to_bytes(base64_string)
  begin
    bytes = Base64.strict_decode64(base64_string)
    bytes
  rescue ArgumentError
    raise_service_error({ message: 'Failed to decode base64 string', base64_string: base64_string })
  end
end

def bytes_from_file(file)

def bytes_from_file(file)
  if file.is_a?(ActionDispatch::Http::UploadedFile)
    file.read
  elsif base64_encoded?(file)
    base64_string_to_bytes(file)
  else
    raise_service_error({
      message: "Can not generate bytes from this file",
      file: file,
    })
  end
end

def bytes_from_url(url, headers: {})

def bytes_from_url(url, headers: {})
  uri, response = download_file_from_url(url, headers: headers).values_at(:uri, :response)
  bytes = response.body
  filename = filename_from_response(response, uri)
  { bytes: bytes, filename: filename }
end

def create_tempfile(filename, bytes)

def create_tempfile(filename, bytes)
  temp_file = Tempfile.new([File.basename(filename, ".*"), File.extname(filename)])
  temp_file.binmode
  temp_file.write(bytes)
  temp_file.rewind
  temp_file
end

def delete_files(*args)

def delete_files(*args)
  pattern = File.join(*args)
  files_to_delete = Dir.glob(pattern)
  files_to_delete.each do |file|
    File.delete(file)
    log_object "File deleted: #{file}"
  end
  log_object "File Deleting Process Finished! (#{files_to_delete.size} files deleted)"
end

def download_file_from_url(url, headers: {})

def download_file_from_url(url, headers: {})
  uri = URI.parse(url)
  request = Net::HTTP::Get.new(uri)
  headers.each { |key, value| request[key] = value }
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
    http.request(request)
  end
  raise_service_error({ message: "Failed to download file", url: url }) unless response.is_a?(Net::HTTPSuccess)
  { uri: uri, response: response }
end

def encode_file_to_base64_from_url(url, headers: {})

def encode_file_to_base64_from_url(url, headers: {})
  uri, response = download_file_from_url(url, headers: headers).values_at(:uri, :response)
  bytes = response.body
  encoded_file = Base64.strict_encode64(bytes)
  filename = filename_from_response(response, uri)
  log_object filename, title: "filename is"
  { filename: filename, encoded_file: encoded_file }
rescue StandardError => e
  raise_service_error({
                        message: "Failed to encode file url",
                        encode_file_error: { message: e.message, backtrace: e.backtrace },
                        url: url
                      })
end

def filename_from_response(response, uri)

def filename_from_response(response, uri)
  content_disposition = response["content-disposition"]
  if content_disposition
    match = content_disposition.match(/filename="?([^"]+)"?/)
    match ? match[1] : File.basename(uri.path)
  else
    File.basename(uri.path)
  end
end

def generate_url_from_file(file:, api_key:)

def generate_url_from_file(file:, api_key:)
  url = URI.parse("https://www.filestackapi.com/api/store/S3?key=#{api_key}")
  request = Net::HTTP::Post.new(url)
  request["Content-Type"] = "application/octet-stream"
  request.body = bytes_from_file(file)
  response = Net::HTTP.start(url.hostname, url.port, use_ssl: true) do |http|
    http.request(request)
  end
  parse_json_error = nil
  if response.is_a?(Net::HTTPSuccess)
    begin
      response_body = JSON.parse(response.body)
    rescue => e
      parse_json_error = {
        message: e.message,
        backtrace: e.backtrace,
      }
    end
    return response_body['url'] if response_body['url'].present?
  end
  raise_service_error({
    message: "Failed to generate url from file",
    url: url,
    file: file,
    request: request,
    response: response,
    response_body: response.body,
    parse_json_error: parse_json_error,
  })
end

def require_relative_folder(*folders)

def require_relative_folder(*folders)
  folder_files = File.join(*folders, "**", "*.rb")
  files_to_require = Dir[folder_files].sort
  # log_object files_to_require, title: 'Files to require are'
  safe_require(files_to_require)
end

def safe_require(missing_files)

def safe_require(missing_files)
  error_counter = {}
  while missing_files.any?
    files_to_require = missing_files
    missing_files = []
    files_to_require.each do |file|
      # log_object "Requiring file: #{file}"
      require_relative file
    rescue NameError => e
      error_counter[file] = error_counter[file].to_i + 1
      if error_counter[file] >= 10
        log_object "Error requiring file: #{file}"
        log_object e, title: "Error is"
        log_object e.backtrace, title: "Error backtrace is"
      end
      missing_files << file if error_counter[file] < 15
    end
  end
end