Imports:
  - Types:
      - DocumentRule
    From: goga/ast/rules/base
  - Types:
      - ImportsNode
      - ImportTypeItemNode
      - ImportUsageItemNode
    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`.

---

"signature_contains_type_name(signature: str, type_name: str) -> result:bool":
  location: tools.py
  annotations: |
    Validates that the signature string contains the specified type name.

    `signature`: signature string in the format "(...) -> return"
    `type_name`: type name to check for inclusion

    `result`: validation result

    Search algorithm:
    - Find all occurrences of `type_name`
    - Check each occurrence for exact match: left and right of `type_name` only
      the characters :, >, (, ), [, ], comma, space, or string boundary are allowed.
      Any other character at the boundary invalidates the match.

    Requirements:
    - Cases that must match as positive:
      - `type_name` = "TypeName" -> (param: TypeName)
      - `type_name` = "TypeName" -> (param: TypeName, param_2: Type)
      - `type_name` = "TypeName" -> (param: Type) -> rv:TypeName
    - Cases that must match as negative:
      - `type_name` = "TypeName" -> (param: TypeNameOne)
      - `type_name` = "TypeName" -> (param: TwoTypeName)
      - `type_name` = "TypeName" -> (param: Type: = "TypeName")

# ******* #
# Imports #
# ******* #

"DocumentRule::ImportsCanNotBeEmpty(name: str = 'imports_can_not_be_empty')":
  location: rules.py
  annotations: |
    Validates `ImportsNode`.

    Rules:
    - The import list must not be empty

    Requirements:
    - The rule applies only when imports are declared in the document

    Error templates:
    - empty: "Imports block in '{doc_path}' is empty — each import must specify at least Types and From"

"DocumentRule::ImportsHasOnlyValidKeys(name: str = 'imports_has_only_valid_keys')":
  location: rules.py
  annotations: |
    Validates `ImportsNode`.

    Rules:
    - Each item in node.data contains only the following keys:
      - Types
      - Usages
      - From

    Error templates:
    - unknown_keys: "Import from '{from_path}' contains unknown keys {unknown_keys} — allowed: Types, Usages, From"

"DocumentRule::ImportItemIsValid(name: str = 'import_item_is_valid')":
  location: rules.py
  annotations: |
    Validates `ImportTypeItemNode` and `ImportUsageItemNode`.

    Rules:
    - Import contains a type or usage to connect

    Requirements:
    - Each Item is validated individually and catches cases where an empty string or null was left in the list

    Error templates:
    - no_type: "Import from '{from_path}' has no {Types | Usages} listed — specify at least one type to import"

"DocumentRule::ImportUsageExists(name: str = 'import_usage_exists')":
  location: rules.py
  annotations: |
    Validates `ImportUsageItemNode`.

    Rules:
    - Imported usage exists at path "{item.from_path}/.usages/{item.usage_name}.md"

    Requirements:
    - Each Item is validated individually

    Error templates:
    - not_found: "Usage '{usage_name}' does not exists on filesystem by path '{usage_md_file_path}'"

"DocumentRule::ImportHasValidFromPath(name: str = 'import_has_valid_from_path')":
  location: rules.py
  annotations: |
    Validates `ImportTypeItemNode` and `ImportUsageItemNode`.

    Rules:
    - Import contains a From path for types or usages
    - Path exists on the filesystem
    - Path does not escape CWD

    Error templates:
    - empty: "Import in '{doc_path}' has empty source path (From field)"
    - not_found: "Source path '{from_path}' in import of types {type_names} not found on filesystem"
    - escapes: "Source path '{from_path}' in import points outside the project root"

"DocumentRule::ImportHasNotDuplicate(name: str = 'import_has_not_duplicate')":
  location: rules.py
  annotations: |
    Validates `ImportsNode`.

    Rules:
    - All type and usage names must be unique across all imported documents

    Error templates:
    - duplicate: "{Type || Usage} '{type_name || usage_name}' is imported more than once: from '{path_a}' and '{path_b}'"

"DocumentRule::ImportIsUsed(name: str = 'import_is_used')":
  location: rules.py
  annotations: |
    Validates `ImportTypeItemNode` and `ImportUsageItemNode`.

    Rules for types:
    - type or alias (if specified) is used in the document in at least one of:
      - Annotations:
        - In document header (header.annotations)
        - In usages (header.usages.item[<name>])
        - Entities (body[*].annotations), including embedded (embedded=True)
        - Routines (body[*].annotations), including embedded (embedded=True)
        - Methods (entity.methods[*].annotations)
        - Properties (entity.properties[*].annotations)
      - Signatures:
        - Entities, including embedded (embedded=True)
        - Routines, including embedded (embedded=True)
        - Methods
      - Mutations:
        - Entities (body[*].mutations), including embedded (embedded=True)

    Rules for usages:
    - usage or alias (if specified) is used in the document in at least one of:
      - Annotations:
        - In document header (header.annotations)
        - In usages (header.usages.item[<name>])
        - Entities (body[*].annotations), including embedded (embedded=True)
        - Routines (body[*].annotations), including embedded (embedded=True)
        - Methods (entity.methods[*].annotations)
        - Properties (entity.properties[*].annotations)

    Requirements:
    - Check types for inclusion in signatures using `signature_contains_type_name`
    - Embedding (embedded) must count as usage and must not trigger an error
    - Usage (practice) is not checked in signatures

    Error templates:
    - unused: "{Type || Usage} '{type_name || usage_name}' was imported, but not used in '{doc_path}'"

---

Author: Mikhail Trifonov
CreatedAt: 14/05/26

Description: |
  Validation rules for imports in CODEMANIFEST documents.
