<commit_before>module RDF::Sesame
  ##
  # A Sesame 2.0-compatible HTTP server.
  #
  # Instances of this class represent Sesame-compatible servers that contain
  # one or more readable and/or writable RDF {Repository repositories}.
  #
  # @example Connecting to a Sesame server
  #   url    = RDF::URI.new("http://localhost:8080/openrdf-sesame")
  #   server = RDF::Sesame::Server.new(url)
  #
  # @example Retrieving the server's protocol version
  #   server.protocol                 #=> 4
  #
  # @example Iterating over available RDF repositories
  #   server.each_repository do |repository|
  #     puts repository.inspect
  #   end
  #
  # @example Finding all readable, non-empty RDF repositories
  #   server.find_all do |repository|
  #     repository.readable? && !repository.empty?
  #   end
  #
  # @example Checking if any RDF repositories are writable
  #   server.any? { |repository| repository.writable? }
  #
  # @example Checking if a specific RDF repository exists on the server
  #   server.has_repository?(:SYSTEM) #=> true
  #   server.has_repository?(:foobar) #=> false
  #
  # @example Obtaining a specific RDF repository
  #   server.repository(:SYSTEM)      #=> RDF::Sesame::Repository(SYSTEM)
  #   server[:SYSTEM]                 #=> RDF::Sesame::Repository(SYSTEM)
  #
  # @see RDF::Sesame
  # @see http://www.openrdf.org/doc/sesame2/system/ch08.html
  class Server
    include Enumerable

    ACCEPT_JSON = {'Accept' => 'application/sparql-results+json'}
    ACCEPT_XML  = {'Accept' => 'application/sparql-results+xml'}
    ACCEPT_BOOL = {'Accept' => 'text/boolean'}

    # @return [RDF::URI]
    attr_reader :url

    # @return [Hash{Symbol => Object}]
    attr_reader :options

    # @return [Connection]
    attr_reader :connection

    ##
    # Initializes this `Server` instance.
    #
    # @param  [RDF::URI]               url
    # @param  [Hash{Symbol => Object}] options
    # @option options [Connection] :connection (nil)
    # @yield  [connection]
    # @yieldparam [Server]
    def initialize(url, options = {}, &block)
      @url = case url
        when Addressable::URI then url
        else Addressable::URI.parse(url.to_s)
      end
      @url = RDF::URI.new(@url)

      @connection = options.delete(:connection) || Connection.new(@url)
      @options    = options

      if block_given?
        case block.arity
          when 1 then block.call(self)
          else instance_eval(&block)
        end
      end
    end

    ##
    # Returns the absolute URI for the given server-relative `path`.
    #
    # @example Getting a Sesame server's URL
    #   server.url            #=> RDF::URI("http://localhost:8080/openrdf-sesame")
    #
    # @example Getting a Sesame server's protocol URL
    #   server.url(:protocol) #=> RDF::URI("http://localhost:8080/openrdf-sesame/protocol")
    #
    # @param  [String, #to_s] path
    # @return [RDF::URI]
    def url(path = nil)
      path ? RDF::URI.new("#{@url}/#{path}") : @url # FIXME
    end

    alias_method :uri, :url

    ##
    # Returns the URL of this server.
    #
    # @return [RDF::URI]
    def to_uri
      url
    end

    ##
    # Returns the URL of this server as a string.
    #
    # @return [String]
    def to_s
      url.to_s
    end

    ##
    # Returns the Sesame server's protocol version.
    #
    # @example Retrieving the protocol version
    #   server.protocol #=> 4
    #
    # @return [Integer]
    # @see    http://www.openrdf.org/doc/sesame2/system/ch08.html#d0e180
    def protocol
      get(:protocol) do |response|
        case response
          when Net::HTTPSuccess
            version = response.body
            version.to_i rescue 0
          else 0
        end
      end
    end

    alias_method :protocol_version, :protocol

    ##
    # Enumerates over each repository on this Sesame server.
    #
    # @yield  [repository]
    # @yieldparam [Repository] repository
    # @return [Enumerable]
    # @see    #repository
    # @see    #repositories
    def each_repository(&block)
      repositories.values.each(&block)
    end

    alias_method :each, :each_repository

    ##
    # Returns `true` if 
    #
    # @param  [id] String
    # @return [Boolean]
    def has_repository?(id)
      repositories.has_key?(id.to_s)
    end

    ##
    # Returns a repository on this Sesame server.
    #
    # @param  [String] id
    # @return [Repository]
    # @see    #repositories
    # @see    #each_repository
    def repository(id)
      repositories[id.to_s]
    end

    alias_method :[], :repository

    ##
    # Returns all repositories on this Sesame server.
    #
    # @return [Hash{String => Repository}]
    # @see    #repository
    # @see    #each_repository
    # @see    http://www.openrdf.org/doc/sesame2/system/ch08.html#d0e204
    def repositories
      require 'json' unless defined?(JSON)

      get(:repositories, ACCEPT_JSON) do |response|
        case response
          when Net::HTTPSuccess
            json = JSON.parse(response.body)
            json['results']['bindings'].inject({}) do |repositories, binding|
              repository = Repository.new({
                :uri      => (uri   = RDF::URI.new(binding['uri']['value'])),
                :id       => (id    = binding['id']['value']),
                :title    => (title = binding['title']['value']),
                :readable => binding['readable']['value'] == 'true',
                :writable => binding['writable']['value'] == 'true',
              })
              repositories.merge({id => repository})
            end
          else [] # FIXME
        end
      end
    end

    protected

      ##
      # Performs an HTTP GET request for the given Sesame server `path`.
      #
      # @param  [String, #to_s]          path
      # @param  [Hash{String => String}] headers
      # @yield  [response]
      # @yieldparam [Net::HTTPResponse] response
      # @return [Net::HTTPResponse]
      def get(path, headers = {}, &block)
        @connection.open do<commit_msg>Implemented RDF::Sesame::Server#inspect.<commit_after>module RDF::Sesame
  ##
  # A Sesame 2.0-compatible HTTP server.
  #
  # Instances of this class represent Sesame-compatible servers that contain
  # one or more readable and/or writable RDF {Repository repositories}.
  #
  # @example Connecting to a Sesame server
  #   url    = RDF::URI.new("http://localhost:8080/openrdf-sesame")
  #   server = RDF::Sesame::Server.new(url)
  #
  # @example Retrieving the server's protocol version
  #   server.protocol                 #=> 4
  #
  # @example Iterating over available RDF repositories
  #   server.each_repository do |repository|
  #     puts repository.inspect
  #   end
  #
  # @example Finding all readable, non-empty RDF repositories
  #   server.find_all do |repository|
  #     repository.readable? && !repository.empty?
  #   end
  #
  # @example Checking if any RDF repositories are writable
  #   server.any? { |repository| repository.writable? }
  #
  # @example Checking if a specific RDF repository exists on the server
  #   server.has_repository?(:SYSTEM) #=> true
  #   server.has_repository?(:foobar) #=> false
  #
  # @example Obtaining a specific RDF repository
  #   server.repository(:SYSTEM)      #=> RDF::Sesame::Repository(SYSTEM)
  #   server[:SYSTEM]                 #=> RDF::Sesame::Repository(SYSTEM)
  #
  # @see RDF::Sesame
  # @see http://www.openrdf.org/doc/sesame2/system/ch08.html
  class Server
    include Enumerable

    ACCEPT_JSON = {'Accept' => 'application/sparql-results+json'}
    ACCEPT_XML  = {'Accept' => 'application/sparql-results+xml'}
    ACCEPT_BOOL = {'Accept' => 'text/boolean'}

    # @return [RDF::URI]
    attr_reader :url

    # @return [Hash{Symbol => Object}]
    attr_reader :options

    # @return [Connection]
    attr_reader :connection

    ##
    # Initializes this `Server` instance.
    #
    # @param  [RDF::URI]               url
    # @param  [Hash{Symbol => Object}] options
    # @option options [Connection] :connection (nil)
    # @yield  [connection]
    # @yieldparam [Server]
    def initialize(url, options = {}, &block)
      require 'addressable/uri' unless defined?(Addressable)
      @url = case url
        when Addressable::URI then url
        else Addressable::URI.parse(url.to_s)
      end
      @url = RDF::URI.new(@url)

      @connection = options.delete(:connection) || Connection.new(@url)
      @options    = options

      if block_given?
        case block.arity
          when 1 then block.call(self)
          else instance_eval(&block)
        end
      end
    end

    ##
    # Returns the absolute URI for the given server-relative `path`.
    #
    # @example Getting a Sesame server's URL
    #   server.url            #=> RDF::URI("http://localhost:8080/openrdf-sesame")
    #
    # @example Getting a Sesame server's protocol URL
    #   server.url(:protocol) #=> RDF::URI("http://localhost:8080/openrdf-sesame/protocol")
    #
    # @param  [String, #to_s] path
    # @return [RDF::URI]
    def url(path = nil)
      path ? RDF::URI.new("#{@url}/#{path}") : @url # FIXME
    end

    alias_method :uri, :url

    ##
    # Returns the URL of this server.
    #
    # @return [RDF::URI]
    def to_uri
      url
    end

    ##
    # Returns the URL of this server as a string.
    #
    # @return [String]
    def to_s
      url.to_s
    end

    ##
    # Returns a developer-friendly representation of this instance.
    #
    # @return [String]
    def inspect
      sprintf("#<%s:%#0x(%s)>", self.class.name, object_id, to_s)
    end

    ##
    # Returns the Sesame server's protocol version.
    #
    # @example Retrieving the protocol version
    #   server.protocol #=> 4
    #
    # @return [Integer]
    # @see    http://www.openrdf.org/doc/sesame2/system/ch08.html#d0e180
    def protocol
      get(:protocol) do |response|
        case response
          when Net::HTTPSuccess
            version = response.body
            version.to_i rescue 0
          else 0
        end
      end
    end

    alias_method :protocol_version, :protocol

    ##
    # Enumerates over each repository on this Sesame server.
    #
    # @yield  [repository]
    # @yieldparam [Repository] repository
    # @return [Enumerable]
    # @see    #repository
    # @see    #repositories
    def each_repository(&block)
      repositories.values.each(&block)
    end

    alias_method :each, :each_repository

    ##
    # Returns `true` if 
    #
    # @param  [id] String
    # @return [Boolean]
    def has_repository?(id)
      repositories.has_key?(id.to_s)
    end

    ##
    # Returns a repository on this Sesame server.
    #
    # @param  [String] id
    # @return [Repository]
    # @see    #repositories
    # @see    #each_repository
    def repository(id)
      repositories[id.to_s]
    end

    alias_method :[], :repository

    ##
    # Returns all repositories on this Sesame server.
    #
    # @return [Hash{String => Repository}]
    # @see    #repository
    # @see    #each_repository
    # @see    http://www.openrdf.org/doc/sesame2/system/ch08.html#d0e204
    def repositories
      require 'json' unless defined?(JSON)

      get(:repositories, ACCEPT_JSON) do |response|
        case response
          when Net::HTTPSuccess
            json = JSON.parse(response.body)
            json['results']['bindings'].inject({}) do |repositories, binding|
              repository = Repository.new({
                :server   => self,
                :uri      => (uri   = RDF::URI.new(binding['uri']['value'])),
                :id       => (id    = binding['id']['value']),
                :title    => (title = binding['title']['value']),
                :readable => binding['readable']['value'] == 'true',
                :writable => binding['writable']['value'] == 'true',
              })
              repositories.merge({id => repository})
            end
          else [] # FIXME
        end
      end
    end

    protected

      ##
      # Performs an HTTP GET request for the given Sesame server `path`.
      #
      # @param  [String, #to_s]          path
      # @param  [Hash{String => String}] headers
      # @yield  [response]
      # @yieldparam [Net::HTTPResponse] response
      # @return [Net::HTTPResponse]
      def get(path, headers = {}, &block)
        @connection.open do
{'fraction_non_alphanumeric': 0.1259325332468375, 'fraction_numerical': 0.005919558871229322, 'mean_word_length': 2.276567481402763, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1171716', 'n_tokens_mistral': 3945, 'n_tokens_neox': 3793, 'n_words': 924}