#!/usr/bin/env python
import json
import colorama
import sys
import re
from termcolor import colored
from tabulate import tabulate

'''
Quick script to format the result of a Semgrep JSON report:
    semgrep scan --force-color --text --metrics off --disable-version-check --oss-only --json-output=findings.json --config auto
    python generate-report-semgrep.py findings.json

Dependencies:
    pip install tabulate colorama termcolor

Semgrep references:
    https://semgrep.dev/docs/cli-reference
    https://github.com/semgrep/semgrep-rules
    https://www.techmagic.co/blog/semgrep
'''


def keep_finding(finding_json_entry):
    # Keep finding by default
    keep = True
    filename = finding_json_entry["path"].replace("\\","/")
    # Exclude test related files
    test_files_detection_regex = r'([\/\-_\s]+test[\/\-_\s]*)'
    if len(re.findall(test_files_detection_regex, filename, re.IGNORECASE)) > 0:
        keep = False
    return keep
    

DESC_LENGTH = 60
report = sys.argv[1]
colorama.init()
with open(report) as f:
    content = f.read()
findings = json.loads(content)
findings_count = len(findings["results"])
print(colored(f"[+] Vulnerabilities ({findings_count}):", "yellow"))
table_headers = ["File", "Line", "Severity", "Description"]
table_rows = []
severities_distribution = {}
for finding in findings["results"]:
    if not keep_finding(finding):
        continue
    filename = finding["path"]
    line = "Col:%s/Line:%s" % (finding["start"]["col"], finding["start"]["line"])
    desc = finding["extra"]["message"][:DESC_LENGTH-3] + "..."
    severity = finding["extra"]["severity"]
    if severity == "ERROR":  # HIGH
        severity_color = "red"
        severity = "HIGH"
    elif severity == "WARNING":  # MEDIUM
        severity_color = "yellow"
        severity = "MEDIUM"
    elif severity == "INFO":  # LOW
        severity_color = "cyan"
        severity = "LOW"
    else:
        severity_color = "white"
    severity = colored(f"{severity}", severity_color, attrs=["bold"])
    if severity not in severities_distribution:
        severities_distribution[severity] = 0
    severities_distribution[severity] += 1
    table_rows.append([filename, line, severity, desc])
table_rows.sort()
print(tabulate(table_rows, headers=table_headers))
print("")
print(colored("[+] Vulnerabilities severity distribution:", "yellow"))
table_headers = ["Severity", "Vulnerability count"]
table_rows.clear()
for severity_name, severity_count in severities_distribution.items():
    table_rows.append([severity_name, severity_count])
table_rows.sort()
print(tabulate(table_rows, headers=table_headers))
