package com.cameleer.server.app.storage;

import com.cameleer.server.app.AbstractPostgresIT;
import com.cameleer.server.app.TestSecurityHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Integration test proving that diagram_content_hash is populated during
 * execution ingestion when a RouteGraph exists for the same route+agent.
 */
class DiagramLinkingIT extends AbstractPostgresIT {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private TestSecurityHelper securityHelper;

    private HttpHeaders authHeaders;

    @BeforeEach
    void setUp() {
        String jwt = securityHelper.registerTestAgent("test-agent-diagram-linking-it");
        authHeaders = securityHelper.authHeaders(jwt);
    }

    @Test
    void diagramHashPopulated_whenRouteGraphExistsBeforeExecution() {
        String graphJson = """
                {
                  "routeId": "diagram-link-route",
                  "description": "Linking test diagram",
                  "version": 1,
                  "nodes": [
                    {"id": "n1", "type": "ENDPOINT", "label": "direct:start"},
                    {"id": "n2", "type": "BEAN", "label": "myBean"}
                  ],
                  "edges": [
                    {"source": "n1", "target": "n2", "edgeType": "FLOW"}
                  ]
                }
                """;

        ResponseEntity<String> diagramResponse = restTemplate.postForEntity(
                "/api/v1/data/diagrams",
                new HttpEntity<>(graphJson, authHeaders),
                String.class);
        assertThat(diagramResponse.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);

        String diagramHash = jdbcTemplate.queryForObject(
                "SELECT content_hash FROM route_diagrams WHERE route_id = 'diagram-link-route' LIMIT 1",
                String.class);
        assertThat(diagramHash).isNotNull().isNotEmpty();

        String executionJson = """
                {
                  "routeId": "diagram-link-route",
                  "exchangeId": "ex-diag-link-1",
                  "correlationId": "corr-diag-link-1",
                  "status": "COMPLETED",
                  "startTime": "2026-03-11T10:00:00Z",
                  "endTime": "2026-03-11T10:00:01Z",
                  "durationMs": 1000,
                  "processors": [
                    {
                      "processorId": "proc-1",
                      "processorType": "bean",
                      "status": "COMPLETED",
                      "startTime": "2026-03-11T10:00:00Z",
                      "endTime": "2026-03-11T10:00:00.500Z",
                      "durationMs": 500,
                      "children": []
                    }
                  ]
                }
                """;

        ResponseEntity<String> execResponse = restTemplate.postForEntity(
                "/api/v1/data/executions",
                new HttpEntity<>(executionJson, authHeaders),
                String.class);
        assertThat(execResponse.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);

        String hash = jdbcTemplate.queryForObject(
                "SELECT diagram_content_hash FROM executions WHERE route_id = 'diagram-link-route'",
                String.class);
        assertThat(hash)
                .isNotNull()
                .isNotEmpty()
                .hasSize(64)
                .matches("[a-f0-9]{64}");
    }

    @Test
    void diagramHashEmpty_whenNoRouteGraphExists() {
        String executionJson = """
                {
                  "routeId": "no-diagram-route",
                  "exchangeId": "ex-no-diag-1",
                  "correlationId": "corr-no-diag-1",
                  "status": "COMPLETED",
                  "startTime": "2026-03-11T10:00:00Z",
                  "endTime": "2026-03-11T10:00:01Z",
                  "durationMs": 1000,
                  "processors": [
                    {
                      "processorId": "proc-no-diag",
                      "processorType": "log",
                      "status": "COMPLETED",
                      "startTime": "2026-03-11T10:00:00Z",
                      "endTime": "2026-03-11T10:00:00.500Z",
                      "durationMs": 500,
                      "children": []
                    }
                  ]
                }
                """;

        ResponseEntity<String> response = restTemplate.postForEntity(
                "/api/v1/data/executions",
                new HttpEntity<>(executionJson, authHeaders),
                String.class);
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);

        String hash = jdbcTemplate.queryForObject(
                "SELECT diagram_content_hash FROM executions WHERE route_id = 'no-diagram-route'",
                String.class);
        assertThat(hash)
                .isNotNull()
                .isEmpty();
    }
}
