<commit_before>require "timeout"
require "net/protocol"

module Cinch
  class IRC
    include Helpers

    # @return [ISupport]
    attr_reader :isupport
    # @return [Bot]
    attr_reader :bot
    # @return [Symbol] The detected network or `:other` if no network
    #   was detected.
    attr_reader :network
    def initialize(bot)
      @bot      = bot
      @isupport = ISupport.new
    end

    # @api private
    # @since 1.2.0
    def setup
      @registration = []
      @network = :other
      @whois_updates = Hash.new {|h, k| h[k] = {}}
      @in_lists      = Set.new
    end

    # @api private
    # @return [Boolean] True if the connection could be established
    def connect
      tcp_socket = nil
      begin
        Timeout::timeout(@bot.config.timeouts.connect) do
          tcp_socket = TCPSocket.new(@bot.config.server, @bot.config.port, @bot.config.local_host)
        end
      rescue Timeout::Error
        @bot.logger.debug("Timed out while connecting")
        return false
      rescue SocketError
        @bot.logger.debug("Could not connect to the IRC server. Please check your network.")
        return false
      rescue => e
        @bot.logger.log_exception(e)
        return false
      end

      if @bot.config.ssl == true || @bot.config.ssl == false
        @bot.logger.debug "Deprecation warning: Beginning from version 1.1.0, @config.ssl should be a set of options, not a boolean value!"
      end

      if @bot.config.ssl == true || (@bot.config.ssl.is_a?(SSLConfiguration) && @bot.config.ssl.use)
        require 'openssl'

        ssl_context = OpenSSL::SSL::SSLContext.new

        if @bot.config.ssl.is_a?(SSLConfiguration)
          if @bot.config.ssl.client_cert
            ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@bot.config.ssl.client_cert))
            ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@bot.config.ssl.client_cert))
          end
          ssl_context.ca_path = @bot.config.ssl.ca_path
          ssl_context.verify_mode = @bot.config.ssl.verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
        else
          ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
        end
        @bot.logger.debug "Using SSL with #{@bot.config.server}:#{@bot.config.port}"

        @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
        @socket.sync = true
        @socket.connect
      else
        @socket = tcp_socket
      end

      @socket = Net::BufferedIO.new(@socket)
      @socket.read_timeout = @bot.config.timeouts.read
      @queue = MessageQueue.new(@socket, @bot)

      return true
    end

    # @api private
    # @since 1.2.0
    def send_login
      message "PASS <PASSWORD>}" if @bot.config.password
      message "NICK #{@bot.generate_next_nick!}"
      message "USER #{@bot.config.user} 0 * :#{@bot.config.realname}"
    end

    # @api private
    # @since 1.2.0
    def start_reading_thread
      Thread.new do
        begin
          while line = @socket.readline
            rescue_exception do
              line = Cinch.encode_incoming(line, @bot.config.encoding)
              parse line
            end
          end
        rescue Timeout::Error
          @bot.logger.debug "Connection timed out."
        rescue EOFError
          @bot.logger.debug "Lost connection."
        rescue => e
          @bot.logger.log_exception(e)
        end

        @socket.close
        @bot.dispatch(:disconnect)
        @bot.handlers.each do |handler|
          handler.stop
        end
      end
    end

    # @api private
    # @since 1.2.0
    def start_sending_thread
      Thread.new do
        rescue_exception do
          @queue.process!
        end
      end
    end

    # @api private
    # @since 1.2.0<commit_msg>do not use the deprecated Bot#dispatch method in irc.rb<commit_after>require "timeout"
require "net/protocol"

module Cinch
  class IRC
    include Helpers

    # @return [ISupport]
    attr_reader :isupport
    # @return [Bot]
    attr_reader :bot
    # @return [Symbol] The detected network or `:other` if no network
    #   was detected.
    attr_reader :network
    def initialize(bot)
      @bot      = bot
      @isupport = ISupport.new
    end

    # @api private
    # @since 1.2.0
    def setup
      @registration = []
      @network = :other
      @whois_updates = Hash.new {|h, k| h[k] = {}}
      @in_lists      = Set.new
    end

    # @api private
    # @return [Boolean] True if the connection could be established
    def connect
      tcp_socket = nil
      begin
        Timeout::timeout(@bot.config.timeouts.connect) do
          tcp_socket = TCPSocket.new(@bot.config.server, @bot.config.port, @bot.config.local_host)
        end
      rescue Timeout::Error
        @bot.logger.debug("Timed out while connecting")
        return false
      rescue SocketError
        @bot.logger.debug("Could not connect to the IRC server. Please check your network.")
        return false
      rescue => e
        @bot.logger.log_exception(e)
        return false
      end

      if @bot.config.ssl == true || @bot.config.ssl == false
        @bot.logger.debug "Deprecation warning: Beginning from version 1.1.0, @config.ssl should be a set of options, not a boolean value!"
      end

      if @bot.config.ssl == true || (@bot.config.ssl.is_a?(SSLConfiguration) && @bot.config.ssl.use)
        require 'openssl'

        ssl_context = OpenSSL::SSL::SSLContext.new

        if @bot.config.ssl.is_a?(SSLConfiguration)
          if @bot.config.ssl.client_cert
            ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@bot.config.ssl.client_cert))
            ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@bot.config.ssl.client_cert))
          end
          ssl_context.ca_path = @bot.config.ssl.ca_path
          ssl_context.verify_mode = @bot.config.ssl.verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
        else
          ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
        end
        @bot.logger.debug "Using SSL with #{@bot.config.server}:#{@bot.config.port}"

        @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
        @socket.sync = true
        @socket.connect
      else
        @socket = tcp_socket
      end

      @socket = Net::BufferedIO.new(@socket)
      @socket.read_timeout = @bot.config.timeouts.read
      @queue = MessageQueue.new(@socket, @bot)

      return true
    end

    # @api private
    # @since 1.2.0
    def send_login
      message "PASS #{@<PASSWORD>.password}" if @bot.config.password
      message "NICK #{@bot.generate_next_nick!}"
      message "USER #{@bot.config.user} 0 * :#{@bot.config.realname}"
    end

    # @api private
    # @since 1.2.0
    def start_reading_thread
      Thread.new do
        begin
          while line = @socket.readline
            rescue_exception do
              line = Cinch.encode_incoming(line, @bot.config.encoding)
              parse line
            end
          end
        rescue Timeout::Error
          @bot.logger.debug "Connection timed out."
        rescue EOFError
          @bot.logger.debug "Lost connection."
        rescue => e
          @bot.logger.log_exception(e)
        end

        @socket.close
        @bot.handlers.dispatch(:disconnect)
        @bot.handlers.each do |handler|
          handler.stop
        end
      end
    end

    # @api private
    # @since 1.2.0
    def start_sending_thread
      Thread.new do
        rescue_exception do
          @queue.process!
        end
      end
    end

    # @api private
    # @since 1.2.0
{'fraction_non_alphanumeric': 0.1090260340954143, 'fraction_numerical': 0.005814721818422096, 'mean_word_length': 2.1092851273623663, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '7611930', 'n_tokens_mistral': 2377, 'n_tokens_neox': 2329, 'n_words': 543}