<commit_before>require_relative 'bot'

require_relative 'botbot_expression'

class Tokenizer
    attr_reader :tokens

    def initialize(raw)
        @raw = raw

        @tokens = []
        current = ''
        quote_open = false
        @raw.each_char do |c|
            if /\s/.match(c) && !quote_open
                if current.length > 0
                    @tokens.push(current)
                end
                current = ''
            elsif c == '"'
                quote_open = !quote_open
            else
                current += c
            end
        end
        if current.length > 0
            @tokens.push(current)
        end

        @rp = 0
    end

    def next()
        n = nil
        if @rp < @tokens.length
            n = @tokens[@rp]
        end
        @rp += 1
        return n
    end
end

class Response
    def initialize(args)
        @args = args
    end

    def do(trigdata, message, room)
    end
end

module RegexBackreference
    def backrefs(rmatch, msg)
        (rmatch.length-1).times do |i|
            msg = msg.gsub("\\#{i+1}", rmatch[i+1])
        end
        return msg
    end
end

class BotbotResponse < Response
    def initialize(args)
        super(args)
        @exp = botbot_expression(@args.join(" "))
    end
end

class SendResponse < BotbotResponse
    include RegexBackreference

    def do(trigdata, message, room)
        @exp.get.each do |msg|
            room.send_message(backrefs(trigdata, msg))
        end
    end
end

class ReplyResponse < BotbotResponse
    include RegexBackreference

    def do(trigdata, message, room)
        @exp.get.each do |msg|
            room.send_message(backrefs(trigdata, msg), message["id"])
        end
    end
end

class NickResponse < BotbotResponse
    include RegexBackreference

    def do(trigdata, message, room)
        nick = @exp.get[0]
        room.send_nick(backrefs(trigdata, nick))
    end
end

RESPONSES = {"send" => lambda do |args| return SendResponse.new(args) end,
             "reply" => lambda do |args| return ReplyResponse.new(args) end,
             "nick" => lambda do |args| return NickResponse.new(args) end
}

class Trigger
    def initialize(args)
        @args = args
    end

    def add(bot, response)
    end
end

class MessageTrigger < Trigger
    def add(bot, response)
        bot.add_handle("send-event", lambda do |m, r|
            reg = Regexp.new(@args.join(" ")).match(m["content"])
            if reg
                response.call(reg, m, r)
                return true
            else
                return false
            end
        end)
    end
end

class TimerTrigger < Trigger
    def add(bot, response)
        bot.add_handle("send-event", lambda do |m, r|
            reg = Regexp.new(@args.slice(1, @args.length).join).match(m["content"])
            if reg
                r.intime(@args[0].to_i, lambda do
                    response.call(reg, m, r)
                end)
            end
            return false
        end)
    end
end

TRIGGERS = {"msg" => lambda do |args| return MessageTrigger.new(args) end,
            "timer" => lambda do |args| return TimerTrigger.new(args) end
}

class Block
    def initialize()
        @trigger = nil
        @responses = []<commit_msg>Added ptimer for push timers.<commit_after>require_relative 'bot'

require_relative 'botbot_expression'

class Tokenizer
    attr_reader :tokens

    def initialize(raw)
        @raw = raw

        @tokens = []
        current = ''
        quote_open = false
        @raw.each_char do |c|
            if /\s/.match(c) && !quote_open
                if current.length > 0
                    @tokens.push(current)
                end
                current = ''
            elsif c == '"'
                quote_open = !quote_open
            else
                current += c
            end
        end
        if current.length > 0
            @tokens.push(current)
        end

        @rp = 0
    end

    def next()
        n = nil
        if @rp < @tokens.length
            n = @tokens[@rp]
        end
        @rp += 1
        return n
    end
end

class Response
    def initialize(args)
        @args = args
    end

    def do(trigdata, message, room)
    end
end

module RegexBackreference
    def backrefs(rmatch, msg)
        (rmatch.length-1).times do |i|
            msg = msg.gsub("\\#{i+1}", rmatch[i+1])
        end
        return msg
    end
end

class BotbotResponse < Response
    def initialize(args)
        super(args)
        @exp = botbot_expression(@args.join(" "))
    end
end

class SendResponse < BotbotResponse
    include RegexBackreference

    def do(trigdata, message, room)
        @exp.get.each do |msg|
            room.send_message(backrefs(trigdata, msg))
        end
    end
end

class ReplyResponse < BotbotResponse
    include RegexBackreference

    def do(trigdata, message, room)
        @exp.get.each do |msg|
            room.send_message(backrefs(trigdata, msg), message["id"])
        end
    end
end

class NickResponse < BotbotResponse
    include RegexBackreference

    def do(trigdata, message, room)
        nick = @exp.get[0]
        room.send_nick(backrefs(trigdata, nick))
    end
end

RESPONSES = {"send" => lambda do |args| return SendResponse.new(args) end,
             "reply" => lambda do |args| return ReplyResponse.new(args) end,
             "nick" => lambda do |args| return NickResponse.new(args) end
}

class Trigger
    def initialize(args)
        @args = args
    end

    def add(bot, response)
    end
end

class MessageTrigger < Trigger
    def add(bot, response)
        bot.add_handle("send-event", lambda do |m, r|
            reg = Regexp.new(@args.join(" ")).match(m["content"])
            if reg
                response.call(reg, m, r)
                return true
            else
                return false
            end
        end)
    end
end

class TimerTrigger < Trigger
    def add(bot, response)
        bot.add_handle("send-event", lambda do |m, r|
            reg = Regexp.new(@args.slice(1, @args.length).join).match(m["content"])
            if reg
                r.intime(@args[0].to_i, lambda do
                    response.call(reg, m, r)
                end)
            end
            return false
        end)
    end
end

class PushTimerTrigger < Trigger
    def initialize(args)
        super(args)
        @ending = {}
    end

    public
    def add(bot, response)
        bot.add_handle("send-event", lambda do |m, r|
            reg = Regexp.new(@args.slice(1, @args.length).join).match(m["content"])
            if reg
                if @ending.include?(r)
                    push_time(r, @args[0].to_i)
                else
                    add_time(r, @args[0].to_i) do
                        response.call(reg, m, r)
                    end
                end
            end
            return false
        end)
    end

    private
    def add_time(room, delay, &blk)
        @ending[room] = Time.now + delay
        room.intime(delay, lambda do
            if @ending[room] < Time.now
                blk.call()
                @ending.delete(room)
            else
                add_time(room, @ending[room] - Time.now, &blk)
            end
        end)
    end

    def push_time(room, delay)
        if @ending.include?(room)
            @ending[room] = Time.now + delay
        end
    end
end

TRIGGERS = {"msg" => lambda do |args| return MessageTrigger.new(args) end,
            "timer" => lambda do |args| return TimerTrigger.new(args) end,
            "ptimer" => lambda do |args| return PushTimerTrigger.new(args) end,
}

class Block
    def initialize()
        @trigger = nil
        @responses = []
{'fraction_non_alphanumeric': 0.10162443144899286, 'fraction_numerical': 0.0029889538661468486, 'mean_word_length': 1.6194690265486726, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 18, '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': '2588047', 'n_tokens_mistral': 2360, 'n_tokens_neox': 2263, 'n_words': 612}