#!/usr/bin/env python3
# encoding: utf-8
# api: python
# description: extract crsvars.conf plugin meta data struct

import re, json
from collections import OrderedDict

src1 = open("./dev/crsvars.conf", "r").read()


# out
pmd1 = OrderedDict()


# read from sample .conf
rx1 = re.compile("""
    (
       (?: ^\# .* \\n  )+
    )

    ^SecAction   \s+[\\\\]?\s*
    \"   ([^\"]+)   \"

""", re.X|re.M|re.I)

for doc, actions in rx1.findall(src1):
    #print("D=",doc, " A=",actions)
    doc = re.sub("^\#\s+", "", doc, 0, re.M).strip()
    desc = re.findall("^(\w+.*)", doc, re.M)[0]
    id = re.findall("id:(\d+)", actions)[0]

    # iterate over multiple setvar:    
    for var,val in re.findall("setvar:'?([\w\.\-]+)=([^\"\'\\\\]+),?'?", actions):
        #print("V=",var, " L=", val)
    
        p = {
            "id": id,
            "name": var,
            "description": desc,
            "type": "str",
            "value": val.strip(","), #  ← let's keep default values here (might strip it in dialog)
            "help": doc
        }
    
        if re.search("anomaly_score|paranoia_level", var):
            p["type"] = "select"
            p["select"] = "0=0 (off)|1=1 (standard)|2=2 (extended)|3=3 (excessive)|4=4 (banking sector)|5=5 (absurd)"
        if var == "id":
            p["type"] = "select"
            p["select"] = "5999=5999|900999=900999"
        elif re.search("tx\.(block_|crs_excl|enforce_|do_|crs_validate|blocking_early)", var): # re.match("^[01]$", val) or re
            p["type"] = "bool"
        elif len(p["value"]) >= 50:
            p["type"] = "text"
            

        pmd1[p["name"]] = p
  


# postprocess
for name,p in pmd1.items():
    if "select" in p:
        kv = p["select"].split("|")
        kv = [v.split("=", 2) for v in kv]
        p["select"] = dict(kv)
    

    
#std
#print(json.dumps(pmd, indent=4))

# write as ordereddict
print("setvar = OrderedDict()")
for k,d in pmd1.items():
    print(f"setvar['{k}'] = " + json.dumps(d, indent=4))

#print(len(pmd2))
