<commit_before>require 'json'

class Array
  def swap!(a,b)
    self[a], self[b] = self[b], self[a]
    self
  end
end



module Lita
  module Handlers
    class Stackstorm < Handler
      # insert handler code here

      config :url, required: true
      config :username, required: true
      config :password, required: true
      config :auth_port, required: false, default: 9100
      config :execution_port, required: false, default: 9101

      class << self
        attr_accessor :token, :expires
      end

      def self.config(config)
        self.token = nil
        self.expires = nil
      end

      route /^st2 login$/, :login, command: false, help: { "st2 login" => "login with st2-api" }
      route /^st2 (ls|aliases|list)$/, :list, command: false, help: { "st2 list" => "list available st2 chatops commands" }

      route /^!(.*)$/, :call_alias, command: false, help: {}

      def auth_builder
        if Integer(config.auth_port) == 443 and config.url.start_with?('https')
          "#{config.url}/auth"
        else
          "#{config.url}:#{config.auth_port}/v1"
        end
      end

      def url_builder
        if Integer(config.execution_port) == 443 and config.url.start_with?('https')
          "#{config.url}/api"
        else
          "#{config.url}:#{config.execution_port}/v1"
        end
      end

      def authenticate
        resp = http.post("#{auth_builder()}/tokens") do |req|
          req.body = {}
          req.headers['Authorization'] = http.set_authorization_header(:basic_auth, config.username, config.password)
        end
        self.class.token = JSON.parse(resp.body)['token']
        self.class.expires = JSON.parse(resp.body)['expiry']
        resp
      end

      def call_alias(msg)
        if expired
          authenticate
        end
        command_array = msg.matches.flatten.first.split
        command_set = Set.new(command_array)

        candidates = redis.scan_each(:match => "#{command_array[0..1].join(' ')}*")

        candidates_set = Set.new(candidates)
        h = candidates_set.classify do |s|
          st = Set.new(s.split /(?<=})\s|\s(?={)|\b\s\b/)
          (st - command_set).length
        end

        if h[h.keys.min].length == 1
          payload = {
            name: command_array.swap!(command_array.length-2,command_array.length-1).join('_'),
            format: h[h.keys.min].to_a.join(" "),
            command: msg.matches.flatten.first,
            user: msg.user.name,
            source_channel: 'chatops',
            notification_channel: 'lita'
          }
          s = make_post_request("/aliasexecution", payload)
          j = JSON.parse(s.body)
          if s.success?
            msg.reply "Got it! Details available at #{config.url}/#/history/#{j['execution']['id']}/general"
          else
            msg.reply "Execution failed with message: #{j['faultstring']}"
          end
        elsif h[h.keys.min].length > 1
          response_text = "possible matches:"
          h[h.keys.min].each do |match|
            response_text+= "\n\t#{match}"
          end
          msg.reply response_text
        else
          msg.reply "Failed! No Aliases Found..."
        end
      end

      def list(msg)
        if expired
          authenticate
        end
        s = make_request("/actionalias", "")
        if JSON.parse(s.body).empty?
          msg.reply "No Action Aliases Registered"
        else
          j = JSON.parse(s.body)
          a = ""
          j.take_while{|i| i['enabled'] }.each do |command|
            command['formats'].each do |format|
              redis.set(format, command['action_ref'])
              a+= "#{format} -> #{command['action_ref']}\n"
            end
          end
          msg.reply a
        end
      end

      def login(msg)
        http_resp = authenticate
        if ![200, 201, 280].index(http_resp.status).nil?<commit_msg>use regex approach like hubot-stackstorm. Delete all keys and restash with regex key and a value containing the alias format and entire json boject from stackstorm.<commit_after>require 'json'

class Array
  def swap!(a,b)
    self[a], self[b] = self[b], self[a]
    self
  end
end



module Lita
  module Handlers
    class Stackstorm < Handler
      # insert handler code here

      config :url, required: true
      config :username, required: true
      config :password, required: true
      config :auth_port, required: false, default: 9100
      config :execution_port, required: false, default: 9101

      class << self
        attr_accessor :token, :expires
      end

      def self.config(config)
        self.token = nil
        self.expires = nil
      end

      route /^st2 login$/, :login, command: false, help: { "st2 login" => "login with st2-api" }
      route /^st2 (ls|aliases|list)$/, :list, command: false, help: { "st2 list" => "list available st2 chatops commands" }

      route /^!(.*)$/, :call_alias, command: false, help: {}

      def auth_builder
        if Integer(config.auth_port) == 443 and config.url.start_with?('https')
          "#{config.url}/auth"
        else
          "#{config.url}:#{config.auth_port}/v1"
        end
      end

      def url_builder
        if Integer(config.execution_port) == 443 and config.url.start_with?('https')
          "#{config.url}/api"
        else
          "#{config.url}:#{config.execution_port}/v1"
        end
      end

      def authenticate
        resp = http.post("#{auth_builder()}/tokens") do |req|
          req.body = {}
          req.headers['Authorization'] = http.set_authorization_header(:basic_auth, config.username, config.password)
        end
        self.class.token = JSON.parse(resp.body)['token']
        self.class.expires = JSON.parse(resp.body)['expiry']
        resp
      end

      def call_alias(msg)
        if expired
          authenticate
        end
        command_array = msg.matches.flatten.first.split
        command_set = Set.new(command_array)

        candidates = redis.scan_each(:match => "#{command_array[0..1].join(' ')}*")

        candidates_set = Set.new(candidates)
        h = candidates_set.classify do |s|
          st = Set.new(s.split /(?<=})\s|\s(?={)|\b\s\b/)
          (st - command_set).length
        end

        if h[h.keys.min].length == 1
          payload = {
            name: command_array.swap!(command_array.length-2,command_array.length-1).join('_'),
            format: h[h.keys.min].to_a.join(" "),
            command: msg.matches.flatten.first,
            user: msg.user.name,
            source_channel: 'chatops',
            notification_channel: 'lita'
          }
          s = make_post_request("/aliasexecution", payload)
          j = JSON.parse(s.body)
          if s.success?
            msg.reply "Got it! Details available at #{config.url}/#/history/#{j['execution']['id']}/general"
          else
            msg.reply "Execution failed with message: #{j['faultstring']}"
          end
        elsif h[h.keys.min].length > 1
          response_text = "possible matches:"
          h[h.keys.min].each do |match|
            response_text+= "\n\t#{match}"
          end
          msg.reply response_text
        else
          msg.reply "Failed! No Aliases Found..."
        end
      end

      def list(msg)
        if expired
          authenticate
        end
        redis.keys.each {|k| redis.del k }
        s = make_request("/actionalias", "")
        if JSON.parse(s.body).empty?
          msg.reply "No Action Aliases Registered"
        else
          j = JSON.parse(s.body)
          a = ""
          extra_params = '(\\s+(\\S+)\\s*=("([\\s\\S]*?)"|\'([\\s\\S]*?)\'|({[\\s\\S]*?})|(\\S+))\\s*)*'
          j.take_while{|i| i['enabled'] }.each do |command|
            command['formats'].each do |format|
              f = format.gsub(/(\s*){{\s*\S+\s*=\s*(?:({.+?}|.+?))\s*}}(\s*)/, '\\s*([\\s\\S]+?)?\\s*')
              f = f.gsub(/\s*{{.+?}}\s*/, '\\s*([\\s\\S]+?)\\s*')
              f = "^\\s*#{f}#{extra_params}\\s*$"
              redis.set(f, {format: format, object: command}.to_json)
              a+= "#{format} -> #{command['action_ref']}\n"
            end
          end
          msg.reply a
        end
      end

      def login(msg)
        http_resp = authenticate
        if ![200, 201, 280].index(http_resp.status).nil?
{'fraction_non_alphanumeric': 0.1493615996145507, 'fraction_numerical': 0.008913514815707058, 'mean_word_length': 1.934959349593496, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, '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': '339831', 'n_tokens_mistral': 2670, 'n_tokens_neox': 2572, 'n_words': 571}