# Selector Consumer Capabilities Report

## Overview

The `SelectorConsumer` (`src/consumers/selector_consumer.rs`) is a Wasot event consumer that filters document events based on CSS-like selectors. It uses the existing selector parser infrastructure to parse selector strings into Abstract Syntax Trees (AST) before matching them against document elements.

## Architecture

### Core Components

1. **Parser Integration**: Uses `parse_selector()` from `src/parsers/selectors/parser.rs` to convert selector strings into AST structures
2. **Event Consumer**: Implements the `Consumer` trait to process Wasot document events
3. **Matching Engine**: Evaluates AST nodes against document metadata (`MetaLine`)

### Data Flow

```
Selector String → Parser → AST → Matching Engine → Filtered Events
     "paragraph"      ↓      ↓          ↓              ↓
                 parse_selector()  SelectorGroup   Match/No Match
```

## Implemented Selector Types

### 1. Universal Selector (`*`)

**Syntax**: `*`

**Matches**: All elements in the document

**Implementation**:
```rust
TagSelector::Universal => {
    // Universal selector matches everything
}
```

**Example**:
```bash
wasot select document.wasot -s "*"
# Matches every block and text element
```

### 2. Type Selectors

**Syntax**: `type-name`

**Matches**: Elements with the exact type name

**Implementation**:
- Compares `meta_line.type_name` with the selector's type name
- Supports composite type names (e.g., `section:features`)

**Examples**:
```bash
wasot select document.wasot -s "paragraph"    # Matches all paragraph blocks
wasot select document.wasot -s "code"         # Matches all code blocks
wasot select document.wasot -s "list:shopping" # Matches specific composite type
```

### 3. ID Selectors

**Syntax**: `#id`

**Matches**: Elements with the specified ID

**Implementation**:
- Compares `meta_line.id.value` with the ID from the selector
- Note: IDs in Wasot are often auto-generated (base36 encoded)

**Examples**:
```bash
wasot select document.wasot -s "#intro"  # Matches block with ID "intro"
wasot select document.wasot -s "#g"      # Matches auto-generated ID "g"
```

### 4. Attribute Presence Selectors

**Syntax**: `[attribute]`

**Matches**: Elements that have the specified attribute (either as positional or keyword argument)

**Implementation**:
- Checks both positional arguments (`meta_line.arguments.args`)
- Checks keyword arguments (`meta_line.arguments.kwargs`)

**Examples**:
```bash
wasot select document.wasot -s "[language]"  # Has 'language' keyword
wasot select document.wasot -s "[important]" # Has 'important' argument
```

### 5. Attribute Negated Presence Selectors

**Syntax**: `[!attribute]`

**Matches**: Elements that do NOT have the specified attribute

**Implementation**:
- Returns `true` only if attribute is absent from both positional and keyword arguments

**Examples**:
```bash
wasot select document.wasot -s "[!width]"    # Blocks without 'width'
wasot select document.wasot -s "[!private]"  # Blocks without 'private'
```

### 6. Attribute Exact Match Selectors

**Syntax**: `[key="value"]`

**Matches**: Elements with a keyword argument matching the exact key-value pair

**Implementation**:
- Only checks keyword arguments (not positional)
- Requires exact string match for both key and value

**Examples**:
```bash
wasot select document.wasot -s '[language="python"]'  # language=python
wasot select document.wasot -s '[type="ordered"]'     # type=ordered
wasot select document.wasot -s '[year="2024"]'        # year=2024
```

## Current Limitations

### 1. No Combinator Support

The following combinators are recognized by the parser but not yet implemented in matching:
- Descendant combinator (space): `ancestor descendant`
- Child combinator (`>`): `parent > child`
- Adjacent sibling (`+`): `element + sibling`
- General sibling (`~`): `element ~ sibling`

**Current Implementation**:
```rust
if !selector.parts.is_empty() {
    // Skip compound selectors with combinators for now
    return false;
}
```

### 2. No Pseudo-Class Support

Pseudo-classes are parsed but not matched:
- `:first-child`, `:last-child`
- `:nth-child(n)`, `:nth-block(n)`, `:nth-text(n)`
- `:not(selector)`

### 3. No OR Selector Support

While the parser supports comma-separated selectors, they must be passed as separate `-s` arguments:
```bash
# Currently requires:
wasot select file.wasot -s "paragraph" -s "code"

# Parser supports but consumer doesn't combine:
# wasot select file.wasot -s "paragraph, code"
```

### 4. No Advanced Attribute Matching

The following attribute selectors are in the AST but not implemented:
- `[key~="value"]` - has key, not value
- `[key^="value"]` - starts with
- `[key$="value"]` - ends with  
- `[key*="value"]` - contains

## Event Processing

### BlockStarted Events

When a block starts:
1. Check if it matches any selector
2. If match found, print the event
3. Push block metadata onto stack for descendant matching (future use)

### TextFinished Events

When text content is complete:
1. Check if parent block matches any selector
2. If match found, print the text event
3. Text inherits matching from its containing block

### BlockFinished Events

When a block ends:
1. Pop the block from the stack
2. No output generated for this event type

## Usage Examples

### Basic Selection
```bash
# Select all paragraphs
cargo run --bin wasot -- select document.wasot -s "paragraph"

# Select specific ID
cargo run --bin wasot -- select document.wasot -s "#main-content"

# Select all blocks
cargo run --bin wasot -- select document.wasot -s "*"
```

### Attribute Selection
```bash
# Has language attribute
cargo run --bin wasot -- select document.wasot -s "[language]"

# Language is Python
cargo run --bin wasot -- select document.wasot -s '[language="python"]'

# Doesn't have width attribute
cargo run --bin wasot -- select document.wasot -s "[!width]"
```

### Multiple Selectors
```bash
# Match multiple types
cargo run --bin wasot -- select document.wasot \
  -s "paragraph" \
  -s "code" \
  -s "blockquote"
```

## Performance Characteristics

### Time Complexity

- **Parse Phase**: O(n) where n is selector string length
- **Match Phase**: 
  - Type/ID matching: O(1)
  - Attribute presence: O(a + k) where a = positional args, k = keyword args
  - Per event: O(s × m) where s = number of selectors, m = matching complexity

### Memory Usage

- Stores parsed AST for all selectors
- Maintains stack of block metadata (grows with nesting depth)
- Memory usage: O(s + d) where s = selector count, d = max nesting depth

## Future Enhancements

### Priority 1: Combinator Support
- Implement descendant matching using the block stack
- Add child combinator checking
- Support sibling relationships

### Priority 2: Pseudo-Class Support
- Implement positional pseudo-classes
- Add `:not()` negation support
- Track element positions for nth-child variants

### Priority 3: Advanced Attribute Matching
- Implement partial matching operators
- Add regex support for attribute values
- Support case-insensitive matching

### Priority 4: Performance Optimizations
- Cache matching results for repeated selectors
- Optimize attribute lookups with indexing
- Implement early termination for impossible matches

## Testing

The selector consumer is tested through:

1. **Integration Tests**: Via the wasot CLI
2. **Demo Script**: `scripts/demo_integrated_selector_usage.sh`
3. **Example Document**: `examples/selectors_demo.wasot`

### Test Coverage

- ✅ Universal selector
- ✅ Type selectors (simple and composite)
- ✅ ID selectors
- ✅ Attribute presence
- ✅ Attribute negation
- ✅ Attribute exact match
- ❌ Combinators (not implemented)
- ❌ Pseudo-classes (not implemented)

## Conclusion

The `SelectorConsumer` provides a solid foundation for CSS-like selection in Wasot documents. It properly uses the parser infrastructure to convert selectors into AST before matching, ensuring maintainability and extensibility. While basic selectors are fully functional, advanced features like combinators and pseudo-classes await implementation.

The architecture is sound and ready for enhancement - the AST-based approach means new selector types can be added by implementing the matching logic without changing the parsing infrastructure.