<commit_before>module Junoser
  class Ruler
    OFFSET = '    '

    def initialize(input)
      @rule = input
    end

    def to_rule
      rule_header << rule << rule_footer
    end

    def rule
      str = @rule.read
      str = process_reserved_element(str)
      str = str.split(/\n/).map {|l| format(process_line(l)) }.join("\n")
    end


    private

    def process_line(str)
      return str if str =~ /^(.* do|end)$/

      str.gsub!(/("[^"]+")/) { "str(#$1)" }  # "foo" -> str("foo")

      str.gsub!(/^(\s*)arg(\.as\(:\S+\))? \($/) { "#{$1}b(arg#$2," }  # arg ( -> b(arg,
      str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+)(\.as\(:\S+\))?(,?)$/) { "#{$1}a(#$2, #$3)#$4#$5" }  # str("foo") bar -> a(str("foo"), bar)
      str.gsub!(/^(\s*)(str\(\S+\)) \((.*)\)(,?)$/) { "#{$1}a(#$2, #$3)#$4" }  # str("foo") (a | b) -> a(str("foo"), a | b)

      str.gsub!(/^(\s*)(str\(\S+\)) \($/) { "#{$1}b(#$2," }  # str("foo") ( -> b(str("foo"),
      str.gsub!(/^(\s*)(\(.*\))(\.as\(:\S\))? \($/) { "#{$1}b(#$2#$3," }  # (a | b) ( -> b((a | b),
      str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+) \($/) { "#{$1}b(a(#$2, #$3)," }  # str("foo") bar ( -> b(a(str("foo"), bar),
      str.gsub!(/^(\s*)(str\(\S+\)) \((.*)\) \($/) { "#{$1}a(#$2, #$3," }  # str("foo") (a | b) ( -> a(str("foo"), a | b,

      str
    end

    def process_reserved_element(str)
      str.gsub! /"\$\S+"/, 'arg'
      str.gsub! '"as-number" arg', 'arg'
      str.gsub! '"confederation-as" arg', 'arg'
      str.gsub! '"equal-literal"', '"="'
      str.gsub! '"plus-literal"', '"+"'
      str.gsub! '"minus-literal"', '"-"'

      str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
      str.gsub! '"vlan" ("id-name" | "all")', '"vlan" ("all" | arg)'
      str.gsub!(/("ssh-\S+") arg/) { "#$1 (quote | arg)" }
      str.gsub! '"metric-value" arg', 'arg'
      str.gsub! '"limit-threshold" arg', 'arg'
      str.gsub! '"filename" arg', 'arg'
      str.gsub! '"description" arg', '"description" (quote | arg)'
      str.gsub! '"as-path-prepend" arg', '"as-path-prepend" (quote | arg)'
      str.gsub! '"filter-name" arg', 'arg'

      str.gsub!(/(s\(\s*)"address" \(\s*arg\s*\)/) { "#{$1}arg" }
      str.gsub!(/^(\s*"idle-timeout" \(\s*c\(\s*c\(\s*"forever",\s*)"timeout" arg/) { "#{$1}arg" }

      str = omit_label(str, 'contents', 'syslog_object')
      str = omit_label(str, 'interface', 'cos_interfaces_type')
      str = omit_label(str, 'interface', 'ir_interfaces_type')
      str = omit_label(str, 'interface', 'interfaces_type')
      str = omit_label(str, 'client-address-list', 'client_address_object')
      str = omit_label(str, 'prefix-list-item', 'prefix_list_items')
      str = omit_label(str, 'instance', 'juniper_routing_instance')
      str = omit_label(str, 'vlan', 'vlan_type')

      str.gsub!(/"icmp"(.*)"icmp6"/) { %["icmpv6"#$1"icmp"] }
      str.gsub!(/"http"(.*)"https"/) { %["https"#$1"http"] }
      str.gsub!(/"snmp"(.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
      str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
      str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
      str.gsub!(/("next-hop" \(\s*c\(\s*c\(\s*[^)]*)"address" \(\s*ipaddr\s*\)/) { "#{$1}ipaddr" }

      %w[metric metric2 metric3 metric4 tag tag2 preference preference2 color color2 local-preference].each do |key|
        str.gsub!(/^(\s*"#{key}" \(\s*c\(\s*c\(\s*)"#{key}" arg/) { "#{$1}arg" }
      end
      str.gsub!(/^(\s*"vrf-target" \(\s*)c\(\s*"community" arg,/) { "#{$1}ca(" }
      str.gsub!(/^(\s*"teardown" \(\s*)c\(/) { "#{$1}sc(" }
      str.gsub!(/^(\s*"file" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }

      str.gsub!(/^(\s*)"inline-services"/) do
        format(['"inline-services" (',
                '  "bandwidth" ("1g" | "10g")',
                ')'], $1)
      end
      str.gsub!(/^(\s*)"ieee-802.3ad" \(\s*c\(\s*"lacp" \(\s*c\(/) do
        format(['"802.3ad" (',
                '  ca(',
                '    "lacp" (',
                '      c(',
                '        "force-up",'], $1)
      end
      str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg/) do
        format(['"as-path" (',
                '  c(',
                '    arg'], $1)
      end
      str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*"path" arg\s*\)/) do
        format(['"as-path" arg (',<commit_msg>Fix: trailing sequence of choices of "as-path"<commit_after>module Junoser
  class Ruler
    OFFSET = '    '

    def initialize(input)
      @rule = input
    end

    def to_rule
      rule_header << rule << rule_footer
    end

    def rule
      str = @rule.read
      str = process_reserved_element(str)
      str = str.split(/\n/).map {|l| format(process_line(l)) }.join("\n")
    end


    private

    def process_line(str)
      return str if str =~ /^(.* do|end)$/

      str.gsub!(/("[^"]+")/) { "str(#$1)" }  # "foo" -> str("foo")

      str.gsub!(/^(\s*)arg(\.as\(:\S+\))? \($/) { "#{$1}b(arg#$2," }  # arg ( -> b(arg,
      str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+)(\.as\(:\S+\))?(,?)$/) { "#{$1}a(#$2, #$3)#$4#$5" }  # str("foo") bar -> a(str("foo"), bar)
      str.gsub!(/^(\s*)(str\(\S+\)) \((.*)\)(,?)$/) { "#{$1}a(#$2, #$3)#$4" }  # str("foo") (a | b) -> a(str("foo"), a | b)

      str.gsub!(/^(\s*)(str\(\S+\)) \($/) { "#{$1}b(#$2," }  # str("foo") ( -> b(str("foo"),
      str.gsub!(/^(\s*)(\(.*\))(\.as\(:\S\))? \($/) { "#{$1}b(#$2#$3," }  # (a | b) ( -> b((a | b),
      str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+) \($/) { "#{$1}b(a(#$2, #$3)," }  # str("foo") bar ( -> b(a(str("foo"), bar),
      str.gsub!(/^(\s*)(str\(\S+\)) \((.*)\) \($/) { "#{$1}a(#$2, #$3," }  # str("foo") (a | b) ( -> a(str("foo"), a | b,

      str
    end

    def process_reserved_element(str)
      str.gsub! /"\$\S+"/, 'arg'
      str.gsub! '"as-number" arg', 'arg'
      str.gsub! '"confederation-as" arg', 'arg'
      str.gsub! '"equal-literal"', '"="'
      str.gsub! '"plus-literal"', '"+"'
      str.gsub! '"minus-literal"', '"-"'

      str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
      str.gsub! '"vlan" ("id-name" | "all")', '"vlan" ("all" | arg)'
      str.gsub!(/("ssh-\S+") arg/) { "#$1 (quote | arg)" }
      str.gsub! '"metric-value" arg', 'arg'
      str.gsub! '"limit-threshold" arg', 'arg'
      str.gsub! '"filename" arg', 'arg'
      str.gsub! '"description" arg', '"description" (quote | arg)'
      str.gsub! '"as-path-prepend" arg', '"as-path-prepend" (quote | arg)'
      str.gsub! '"filter-name" arg', 'arg'

      str.gsub!(/(s\(\s*)"address" \(\s*arg\s*\)/) { "#{$1}arg" }
      str.gsub!(/^(\s*"idle-timeout" \(\s*c\(\s*c\(\s*"forever",\s*)"timeout" arg/) { "#{$1}arg" }

      str = omit_label(str, 'contents', 'syslog_object')
      str = omit_label(str, 'interface', 'cos_interfaces_type')
      str = omit_label(str, 'interface', 'ir_interfaces_type')
      str = omit_label(str, 'interface', 'interfaces_type')
      str = omit_label(str, 'client-address-list', 'client_address_object')
      str = omit_label(str, 'prefix-list-item', 'prefix_list_items')
      str = omit_label(str, 'instance', 'juniper_routing_instance')
      str = omit_label(str, 'vlan', 'vlan_type')

      str.gsub!(/"icmp"(.*)"icmp6"/) { %["icmpv6"#$1"icmp"] }
      str.gsub!(/"http"(.*)"https"/) { %["https"#$1"http"] }
      str.gsub!(/"snmp"(.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
      str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
      str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
      str.gsub!(/("next-hop" \(\s*c\(\s*c\(\s*[^)]*)"address" \(\s*ipaddr\s*\)/) { "#{$1}ipaddr" }

      %w[metric metric2 metric3 metric4 tag tag2 preference preference2 color color2 local-preference].each do |key|
        str.gsub!(/^(\s*"#{key}" \(\s*c\(\s*c\(\s*)"#{key}" arg/) { "#{$1}arg" }
      end
      str.gsub!(/^(\s*"vrf-target" \(\s*)c\(\s*"community" arg,/) { "#{$1}ca(" }
      str.gsub!(/^(\s*"teardown" \(\s*)c\(/) { "#{$1}sc(" }
      str.gsub!(/^(\s*"file" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }

      str.gsub!(/^(\s*)"inline-services"/) do
        format(['"inline-services" (',
                '  "bandwidth" ("1g" | "10g")',
                ')'], $1)
      end
      str.gsub!(/^(\s*)"ieee-802.3ad" \(\s*c\(\s*"lacp" \(\s*c\(/) do
        format(['"802.3ad" (',
                '  ca(',
                '    "lacp" (',
                '      c(',
                '        "force-up",'], $1)
      end
      str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg,/) do
        format(['"as-path" (',
                '  ca('], $1)
      end
      str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*"path" arg\s*\)/) do
        format(['"as-path" arg (',
{'fraction_non_alphanumeric': 0.3176178660049628, 'fraction_numerical': 0.013309271373787504, 'mean_word_length': 2.4090734332948864, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, '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': '617658', 'n_tokens_mistral': 3908, 'n_tokens_neox': 3772, 'n_words': 555}