# Architecture Rules - Language & I18N Rules
# Rules for internationalization and language handling

language_rules:

  - id: "LANG-001"
    name: "Only use supported language codes"
    severity: "error"
    description: |
      Only use supported language codes: en, fr, de, lb
      Never use full language names or invalid codes.

      SUPPORTED CODES:
      - en: English (fallback language)
      - fr: French (default for Luxembourg)
      - de: German
      - lb: Luxembourgish

      WRONG:
        language = "english"  # Use "en"
        language = "french"   # Use "fr"
        language = "lux"      # Use "lb"

      RIGHT:
        language = "en"
        language = "fr"
        language = "de"
        language = "lb"
    pattern:
      file_pattern: "**/*.py"
      anti_patterns:
        - "'english'"
        - "'french'"
        - "'german'"
        - "'luxembourgish'"
        - "'lux'"

  - id: "LANG-002"
    name: "Never use inline Alpine.js x-data with Jinja for language selector"
    severity: "error"
    description: |
      Never put complex JavaScript objects inline in x-data when using Jinja variables.
      Jinja outputs Python lists, not JSON, which breaks JavaScript parsing.

      WRONG (inline with Jinja):
        <div x-data="{
            languages: {{ vendor.storefront_languages }},
            ...
        }">

      RIGHT (function call with single quotes for x-data attribute):
        <div x-data='languageSelector("{{ lang }}", {{ langs|tojson }})'>

      IMPORTANT: Use SINGLE QUOTES for the x-data attribute value because
      |tojson outputs double quotes in JSON arrays. Single quotes on the
      outside prevent the JSON double quotes from breaking HTML parsing.

      The languageSelector function must be defined in:
      - static/shop/js/shop-layout.js (for storefront)
      - static/vendor/js/init-alpine.js (for vendor dashboard)
      - static/admin/js/init-alpine.js (for admin dashboard)
    pattern:
      file_pattern: "app/templates/**/*.html"
      anti_patterns:
        - 'x-data="{\s*.*languages:'
        - 'x-data="{\s*.*languageNames:'
        - 'x-data="{\s*.*languageFlags:'
      exceptions:
        - "partials/header.html"

  - id: "LANG-003"
    name: "Use tojson correctly for Python lists in templates"
    severity: "error"
    description: |
      When passing Python lists to JavaScript, use tojson appropriately:

      IN HTML ATTRIBUTES (x-data, data-*, etc.):
        Use SINGLE QUOTES for the attribute and |tojson for the array:
        <div x-data='languageSelector("fr", {{ langs|tojson }})'>
        <!-- Renders: x-data='languageSelector("fr", ["fr", "de"])' -->

        The single quotes on x-data prevent JSON double quotes from
        breaking the HTML attribute parsing.

      IN <script> BLOCKS:
        Use |tojson|safe - raw JSON is valid inside script tags:
        <script>
          const languages = {{ vendor.storefront_languages|tojson|safe }};
        </script>

      WRONG (double quotes with tojson - JSON quotes break the attribute):
        <div x-data="init({{ data|tojson }})">
        <!-- Outputs: x-data="init(["a", "b"])" - breaks at first [ -->
    pattern:
      file_pattern: "app/templates/**/*.html"
      required_with_jinja_array:
        - "|tojson"

  - id: "LANG-004"
    name: "Language selector function must be exported to window"
    severity: "error"
    description: |
      The languageSelector function must be defined and exported to window
      in the appropriate JavaScript file.

      Required in static/shop/js/shop-layout.js:
        function languageSelector(currentLang, enabledLanguages) { ... }
        window.languageSelector = languageSelector;

      Required in static/vendor/js/init-alpine.js:
        function languageSelector(currentLang, enabledLanguages) { ... }
        window.languageSelector = languageSelector;
    pattern:
      file_pattern: "static/shop/js/shop-layout.js"
      required_patterns:
        - "function languageSelector"
        - "window.languageSelector"
      file_pattern: "static/vendor/js/init-alpine.js"
      required_patterns:
        - "function languageSelector"
        - "window.languageSelector"

  - id: "LANG-005"
    name: "Use native language names in language selector"
    severity: "error"
    description: |
      Language names must be in their native form, not English.

      WRONG (English names):
        languageNames: {
            'fr': 'French',
            'de': 'German',
            'lb': 'Luxembourgish'
        }

      RIGHT (native names):
        languageNames: {
            'en': 'English',
            'fr': 'Francais',
            'de': 'Deutsch',
            'lb': 'Letzebuergesch'
        }
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "'fr':\\s*'French'"
        - "'de':\\s*'German'"
        - "'lb':\\s*'Luxembourgish'"

  - id: "LANG-006"
    name: "Use correct flag codes for languages"
    severity: "error"
    description: |
      Flag codes must map correctly to flag-icons library codes.

      CORRECT MAPPINGS:
      - en -> gb (Great Britain flag for English)
      - fr -> fr (France flag)
      - de -> de (Germany flag)
      - lb -> lu (Luxembourg flag)

      WRONG:
        'en': 'us'  # US flag incorrect for general English
        'en': 'en'  # 'en' is not a valid flag code
        'lb': 'lb'  # 'lb' is not a valid flag code

      RIGHT:
        'en': 'gb',
        'fr': 'fr',
        'de': 'de',
        'lb': 'lu'
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "'en':\\s*'us'"
        - "'en':\\s*'en'"
        - "'lb':\\s*'lb'"

  - id: "LANG-007"
    name: "Storefront must respect vendor's enabled languages"
    severity: "error"
    description: |
      Shop/storefront templates must only show languages enabled by the vendor.
      Use vendor.storefront_languages, not a hardcoded list.

      WRONG (hardcoded):
        {% set enabled_langs = ['en', 'fr', 'de', 'lb'] %}

      RIGHT (from vendor config):
        {% set enabled_langs = vendor.storefront_languages if vendor and vendor.storefront_languages else ['fr', 'de', 'en'] %}
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      required_for_lang_selector:
        - "vendor.storefront_languages"

  - id: "LANG-008"
    name: "Language API endpoint must use POST method"
    severity: "error"
    description: |
      The language set API must be called with POST method, not GET.

      WRONG:
        fetch('/api/v1/language/set?lang=' + lang)
        fetch('/api/v1/language/set', { method: 'GET' })

      RIGHT:
        fetch('/api/v1/language/set', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ language: lang })
        })
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "/language/set.*method.*GET"
        - "/language/set\\?lang="

  - id: "LANG-009"
    name: "Always provide language default in templates"
    severity: "error"
    description: |
      When accessing request.state.language, always provide a default value.

      WRONG:
        {{ request.state.language }}  <!-- May be None -->

      RIGHT:
        {{ request.state.language|default("fr") }}
    pattern:
      file_pattern: "app/templates/**/*.html"
      anti_patterns:
        - 'request\\.state\\.language[^|]'
      required_pattern: 'request\\.state\\.language\\|default'

  - id: "LANG-010"
    name: "Translation files must be valid JSON"
    severity: "error"
    description: |
      All translation files in static/locales/ must be valid JSON.
      No trailing commas, proper quoting, etc.

      Files required:
      - static/locales/en.json
      - static/locales/fr.json
      - static/locales/de.json
      - static/locales/lb.json
    pattern:
      file_pattern: "static/locales/*.json"
      check: "valid_json"
