#!/usr/bin/env python
"""Generate wmd/sanitize_config.js from askbot/const/sanitizer_config.py.

This script is the bridge that keeps the JS DOMPurify configuration
in sync with the Python bleach configuration. It loads the Python
constants directly via importlib (no Django required) and writes
a JS file that exposes PURIFY_CONFIG and ALLOWED_ATTR_MAP globals.

Usage:
    cd askbot/media
    python bin/sync_sanitize_config.py
"""
import importlib.util
import json
import os
import sys

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
MEDIA_DIR = os.path.dirname(SCRIPT_DIR)  # askbot/media
OUTPUT_PATH = os.path.join(MEDIA_DIR, 'wmd', 'sanitize_config.js')

# Path to the Python source of truth
CONFIG_PATH = os.path.join(MEDIA_DIR, '..', 'const', 'sanitizer_config.py')
CONFIG_PATH = os.path.normpath(CONFIG_PATH)


def load_config():
    """Load sanitizer_config.py without importing askbot or Django."""
    spec = importlib.util.spec_from_file_location('sanitizer_config', CONFIG_PATH)
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod


def build_js(mod):
    """Build the JS source string from the Python constants."""
    # Merge tags: ALLOWED_HTML_ELEMENTS + MARKDOWN_EXTRA_TAGS
    allowed_tags = sorted(set(mod.ALLOWED_HTML_ELEMENTS) | set(mod.MARKDOWN_EXTRA_TAGS))

    # Merge attributes: ALLOWED_HTML_ATTRIBUTES + MARKDOWN_EXTRA_ATTRIBUTES
    attr_map = {}
    for source in (mod.ALLOWED_HTML_ATTRIBUTES, mod.MARKDOWN_EXTRA_ATTRIBUTES):
        for tag, attrs in source.items():
            if tag in attr_map:
                attr_map[tag] = sorted(set(attr_map[tag]) | set(attrs))
            else:
                attr_map[tag] = sorted(attrs)

    # Flat list of all unique attribute names (for DOMPurify ALLOWED_ATTR)
    all_attrs = sorted({attr for attrs in attr_map.values() for attr in attrs})

    # Sort the attr_map by tag name for stable output
    attr_map = dict(sorted(attr_map.items()))

    lines = [
        '/* Auto-generated by bin/sync_sanitize_config.py — do not edit */',
        '/* eslint-disable */',
        'var PURIFY_CONFIG = {',
        '  ALLOWED_TAGS: {},'.format(json.dumps(allowed_tags)),
        '  ALLOWED_ATTR: {}'.format(json.dumps(all_attrs)),
        '};',
        '',
        'var ALLOWED_ATTR_MAP = {};'.format(
            json.dumps(attr_map, indent=2)
        ),
        '',
    ]
    return '\n'.join(lines)


def main():
    mod = load_config()
    js_source = build_js(mod)

    os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
    with open(OUTPUT_PATH, 'w') as fh:
        fh.write(js_source)

    print(f'Wrote {OUTPUT_PATH}')
    return 0


if __name__ == '__main__':
    sys.exit(main())
