package com.ankurm.dockercompose;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.autoconfigure.JdbcConnectionDetails;
import org.springframework.boot.test.context.SpringBootTest;

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

/**
 * No spring.datasource.* property appears anywhere in this module -
 * spring-boot-docker-compose is what finds compose.yaml, runs
 * "docker compose up" for the postgres service it declares, and
 * registers the JdbcConnectionDetails bean this test autowires,
 * pointed at the real container Docker just started. With no host
 * port pinned in compose.yaml ("ports: ['5432']"), Docker Compose
 * publishes the container's 5432 to a random free port on the host -
 * so a JDBC URL hard-coded to port 5432 would be wrong most of the
 * time. Asserting the port in jdbcUrl() is NOT 5432 is the whole
 * point: it proves the connection really came from the dynamically
 * mapped port, not a guess.
 */
@SpringBootTest(classes = DockerComposeDemoApplication.class)
class DockerComposeConnectionTest {

    @Autowired
    JdbcConnectionDetails connectionDetails;

    @Autowired
    WidgetRepository widgetRepository;

    @Test
    void jdbcConnectionDetailsPointsAtTheRealContainerPortNotTheDefault() {
        String jdbcUrl = connectionDetails.getJdbcUrl();

        assertThat(jdbcUrl).startsWith("jdbc:postgresql://");
        assertThat(jdbcUrl).doesNotContain(":5432/");
        assertThat(connectionDetails.getUsername()).isEqualTo("appuser");

        Transcript t = new Transcript("32-connection-details.txt");
        t.line("JdbcConnectionDetails.getJdbcUrl() = %s", jdbcUrl);
        t.line("compose.yaml published container port 5432 to this host port - not the default");
        t.line("username = %s (from POSTGRES_USER in compose.yaml, picked up automatically)", connectionDetails.getUsername());
        t.write();
    }

    @Test
    void widgetRepositoryActuallyReadsAndWritesThroughTheComposeStartedContainer() {
        widgetRepository.createTable();
        int before = widgetRepository.count();

        int id = widgetRepository.insert("left-handed widget");
        String name = widgetRepository.nameOf(id);
        int after = widgetRepository.count();

        assertThat(name).isEqualTo("left-handed widget");
        assertThat(after - before).isEqualTo(1);

        Transcript t = new Transcript("32-widget-roundtrip.txt");
        t.line("rows before insert: %d", before);
        t.line("INSERT ... RETURNING id -> id=%d", id);
        t.line("SELECT name FROM widget WHERE id=%d -> \"%s\"", id, name);
        t.line("rows after insert: %d (delta %d)", after, after - before);
        t.write();
    }
}
