You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: s3_storage.rb
    path of file: ./repos/fastlane/match/lib/match/storage
    
    the code of the file until where you have to start completion: require 'fastlane_core/command_executor'
require 'fastlane_core/configuration/configuration'
require 'fastlane/helper/s3_client_helper'

require_relative '../options'
require_relative '../module'
require_relative '../spaceship_ensure'
require_relative './interface'

module Match
  module Storage
    # Store the code signing identities on AWS S3
    class S3Storage < Interface
      attr_reader :s3_bucket
      attr_reader :s3_region
      attr_reader :s3_client
      attr_reader :s3_object_prefix
      attr_reader :readonly
      attr_reader :username
      attr_reader :team_id
      attr_reader :team_name
      attr_reader :api_key_path
      attr_reader :api_key

      def self.configure(params)
        s3_region = params[:s3_regi
    
      def download
        # Check if we already have a functional working_directory
        return if @working_directory && Dir.exist?(@working_directory)

        # No existing working directory, creating a new one now
        self.working_directory = Dir.mktmpdir

        s3_client.find_bucket!(s3_bucket).objects(prefix: s3_object_prefix).each do |object|

          # Prevent download if the file path is a directory.
          # We need to check if string ends with "/" instead of using `File.directory?` because
          # the string represent a remote location, not a local file in disk.
          next if object.key.end_with?("/")

          file_path = strip_s3_object_prefix(object.key) # :s3_object_prefix:team_id/path/to/file

          # strip s3_prefix from file_path
          download_path = File.join(self.working_directory, file_path)

          FileUtils.mkdir_p(File.expand_path("..", download_path))
          UI.verbose("Downloading file from S3 '#{file_path}' on bucket #{self.s3_bucket}")

          object.download_file(download_path)
        end
        UI.verbose("Successfully downloaded files from S3 to #{self.working_directory}")
      end

      # Returns a short string describing + identifying the current
      # storage backend. This will be printed when nuking a storage
      def human_readable_description
        return "S3 Bucket [#{s3_bucket}] on region #{s3_region}"
      end

      def upload_files(files_to_upload: [], custom_message: nil)
        # `files_to_upload` is an array of files that need to be uploaded to S3
        # Those doesn't mean they're new, it might just be they're changed
        # Either way, we'll upload them using the same technique

        files_to_upload.each do |file_name|
          # Go from
          #   "/var/folders/px/bz2kts9n69g8crgv4jpjh6b40000gn/T/d20181026-96528-1av4gge/:team_id/profiles/development/Development_me.mobileprovision"
          # to
          #   ":s3_object_prefix:team_id/profiles/development/Development_me.mobileprovision"
          #
          target_path = s3_object_path(file_name)
          UI.verbose("Uploading '#{target_path}' to S3 Storage...")

          body = File.read(file_name)
          acl = 'private'
          s3_url = s3_client.upload_file(s3_bucket, target_path, body, acl)
          UI.verbose("Uploaded '#{s3_url}' to S3 Storage.")
        end
      end

      def delete_files(files_to_delete: [], custom_message: nil)
        files_to_delete.each do |file_name|
          target_path = s3_object_path(file_name)
          UI.verbose("Deleting '#{target_path}' from S3 Storage...")
          s3_client.delete_file(s3_bucket, target_path)
        end
      end

      def skip_docs
        false
      end

      def list_files(file_name: "", file_ext: "")
        Dir[File.join(working_directory, self.team_id, "**", file_name, "*.#{file_ext}")]
      end

      # Implement this for the `fastlane match init` command
      # This method must return the content of the Matchfile
      # that should be generated
      def generate_matchfile_content(template: nil)
        return "s3_bucket(\"#{self.s3_bucket}\")"
      end

      private

      def s3_object_path(file_name)
        sanitized = sanitize_file_name(file_name)
        return sanitized if sanitized.start_with?(s3_object_prefix)

        s3_object_prefix + sanitized
      end

      def strip_s3_object_prefix(object_path)
        object_path.gsub(/^#{s3_object_prefix}/, "")
      end

      def sanitize_file_name(file_name)
        file_name.gsub(self.working_directory + "/", "")
      end

      def currently_used_team_id
        if self.readonly
          # In readonly mode, we still want to see if the user provided a team_id
          # see `prefixed_working_directory` comments for more details
          return self.team_id
        else
          UI.user_error!("The `team_id` option is required. fastlane cannot automatically determine portal team id via the App Store Connect API (yet)") if self.team_id.to_s.empty?

          spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name, api_token)
          return spaceship.team_id
        end
      end

      def api_token
        api_token = Spaceship::ConnectAPI::Token.from(hash: self.api_key, filepath: self.api_key_path)
        api_token ||= Spaceship::ConnectAPI.token
        return api_token
      end
    end
  end
end