# Implementation Details: Trigger Detection with JDT

## 1. Finding `sendEvent` Calls
We can use an `ASTVisitor` to find all `MethodInvocation` nodes.

```java
public class SendEventVisitor extends ASTVisitor {
    @Override
    public boolean visit(MethodInvocation node) {
        if ("sendEvent".equals(node.getName().getIdentifier())) {
            // Found a call!
            // 1. Extract event (first argument)
            // 2. Identify the enclosing method and class
        }
        return super.visit(node);
    }
}
```

### Challenges in Event Extraction
Events can be:
- Enum constants: `Events.SUBMIT`
- Strings: `"SUBMIT"`
- Variables: `sm.sendEvent(eventFromPayload)` (Hard to resolve statically)

We should reuse `CodebaseContext.resolveState` logic (which is basically resolving an expression to a value/fqn).

## 2. Identifying Enclosing Context
Once a `sendEvent` is found, we can traverse up the AST to find the `MethodDeclaration` and `TypeDeclaration`.

```java
ASTNode parent = node.getParent();
while (parent != null && !(parent instanceof MethodDeclaration)) {
    parent = parent.getParent();
}
// parent is now the MethodDeclaration
```

### 2. Extracting Annotations
From `MethodDeclaration`, we can check for mappings:
- `@PostMapping`, `@GetMapping`, etc.
- `@KafkaListener`: Extract `topics`, `groupId`.
- `@RabbitListener`: Extract `queues`, `bindings` (Exchange/RoutingKey).

From `TypeDeclaration`, we can check for:
- `@RestController`, `@Controller`
- `@RequestMapping` at class level (to get base path)

## 3. Specialized WebFlux Analysis

### Annotation-based WebFlux
This is largely identical to Spring MVC. The challenge is if the `sendEvent` is wrapped in a reactive operator.
```java
public Mono<Void> submit(Order order) {
    return service.save(order)
                  .doOnNext(o -> stateMachine.sendEvent(Events.SUBMIT))
                  .then();
}
```
**Static Strategy**: We need to look inside `LambdaExpression` nodes passed to reactive operators (`doOnNext`, `flatMap`, `map`, `subscribe`). The `ASTVisitor` should traverse into these lambdas.

### Functional WebFlux (RouterFunctions)
Functional endpoints are often defined as Beans returning `RouterFunction`.
```java
@Bean
public RouterFunction<ServerResponse> route(OrderHandler handler) {
    return RouterFunctions.route(POST("/orders"), handler::submitOrder);
}
```
**Static Strategy**:
1. Find methods returning `RouterFunction`.
2. Analyze the `MethodInvocation` chain (`route`, `andRoute`, `nest`).
3. Extract the URI pattern and the `HandlerFunction` reference.
4. If the handler is a method reference (`handler::submitOrder`), link it to the corresponding `MethodDeclaration`.

## 4. Specialized RabbitMQ Analysis
`@RabbitListener` can be complex:
```java
@RabbitListener(bindings = @QueueBinding(
    value = @Queue(value = "orderQueue", durable = "true"),
    exchange = @Exchange(value = "orderExchange"),
    key = "order.created"
))
public void onOrder(Order order) { ... }
```
**Static Strategy**:
1. Find `@RabbitListener`.
2. If it has `bindings`, drill down into `@QueueBinding`, `@Queue`, `@Exchange` to extract the topology.
3. If it only has `queues`, resolve the queue name (might be a SpEL expression or property placeholder, which we can try to resolve or just keep as-is).

## 5. Indirect Flow Detection (The "Service Link")
If the project has multiple state machines, we need to know which one is being targeted.
Usually, this is done via:
- Autowiring by type: `StateMachine<States, Events> sm;`
- Autowiring by name: `@Qualifier("mySm") StateMachine sm;`

We can look at the fields of the class where `sendEvent` is called.

## 6. Output Enhancement
The `Exporter` should be modified to:
- In DOT: Add nodes for Endpoints/Listeners and link them to the Events/Transitions.
- In SCXML: Add metadata to transitions.
