Imports:
  - Types:
      - DocumentRule
    From: goga/ast/rules/base
  - Types:
      - UsagesNode
      - UsageItemNode
      - AnnotationsNode
      - HeaderNode
      - RoutineTypeNode
      - EntityTypeNode
      - MethodNode
      - PropertyNode
    From: goga/ast/nodes

Usages:
  conventions: .goga/usages/conventions.md

Annotations: |
  When developing and testing: follow the practice `conventions`.
  All types are mutations of `DocumentRule`.

---

# ****** #
# Usages #
# ****** #

"DocumentRule::AllUsagesIsUsed(name: str = 'all_usages_is_used')":
  location: rules.py
  annotations: |
    Validates `UsagesNode`.

    Rules:
    - All declared usages are used in `AnnotationsNode` of the document in the following nodes:
      - `HeaderNode`
      - `UsageItemNode`
      - `RoutineTypeNode`
      - `EntityTypeNode`
      - `MethodNode`
      - `PropertyNode`

    Requirements:
      - The usage name must be referenced in at least one `AnnotationsNode`

    Error templates:
    - unused: "Usage '{usage_name}' is declared but not referenced in any annotation — either use it or remove the declaration"

"DocumentRule::UsageFilepathExists(name: str = 'usage_filepath_exists')":
  location: rules.py
  annotations: |
    Validates `UsageItemNode`.

    Rules:
    - filepath is resolved relative to project root
    - filepath contains prefix .goga/usages/
    - File at filepath exists on the filesystem

    Requirements:
    - Base path for validation is project root (CWD)
    - Each UsageItemNode with annotations.filepath not None and not empty is validated
    - Usages with annotations.text (inline) are skipped
    - Usages with annotations.url are skipped

    Error templates:
    - outside_usages: "Usage '{usage_name}' filepath '{filepath}' is not built from the root of the project"
    - incorrect_path: "Usage '{usage_name}' filepath '{filepath}' is not built from '.goga/usages/'"
    - not_found: "Usage '{usage_name}' filepath '{filepath}' does not exist on filesystem"

"DocumentRule::UsageUrlIsAccessible(name: str = 'usage_url_is_accessible')":
  location: rules.py
  annotations: |
    Validates `UsageItemNode`.

    Rules:
    - URL responds with HTTP status 200 (OK)

    Requirements:
    - Each UsageItemNode with annotations.url not None and not empty is validated
    - Usages with annotations.text (inline) are skipped
    - Usages with annotations.filepath are skipped
    - On network error (timeout, connection error) — validation error
    - Use HEAD request for efficiency (fallback to GET if server does not support it)
    - Request timeout — 5 seconds
    - URL validation result is cached: on repeated check of the same URL
      the stored result is returned without a new network request
    - Cache is stored in the rule instance as a dict, key is the URL
    - Cache accumulates when traversing all documents in a single linter session

    Error templates:
    - not_accessible: "Usage '{usage_name}' URL '{url}' returned HTTP {status_code} — expected 200"
    - request_failed: "Usage '{usage_name}' URL '{url}' request failed: {error_message}"

"DocumentRule::UsageLinksHasNotConflicts(name: str = 'usage_links_has_not_conflicts')":
  location: rules.py
  annotations: |
    Validates `UsagesNode`.

    Rules:
    - All usage item names must not conflict with imported type names
      (conflicts can be resolved via alias for the type)
    - All usage item names must not conflict with entity and routine names

    Error templates:
    - import_conflict: "Usage key '{name}' conflicts with imported type '{type_name}' — rename the usage or use an alias in Imports"
    - entity_conflict: "Usage key '{name}' conflicts with {kind} '{entity_name}' — rename the usage to avoid ambiguity"

---

Author: Mikhail Trifonov
CreatedAt: 14/05/26

Description: |
  Validation rules for usages in CODEMANIFEST documents.
