package org.raddatz.familienarchiv.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.Flyway;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;
import java.util.Map;

@Configuration
@RequiredArgsConstructor
@Slf4j
public class FlywayConfig {

    private final DataSource dataSource;
    private final Environment environment;

    @Bean(name = "flyway")
    public Flyway flyway() {
        log.info("Running Flyway migrations...");
        Flyway flyway = Flyway.configure()
                .dataSource(dataSource)
                .locations("classpath:db/migration")
                .placeholders(Map.of("grafanaDbPassword", resolveGrafanaDbPassword()))
                .baselineOnMigrate(true)
                .baselineVersion("4")
                .load();
        var result = flyway.migrate();
        log.info("Flyway: {} migration(s) applied.", result.migrationsExecuted);
        return flyway;
    }

    // Fail-closed: refuse to boot when GRAFANA_DB_PASSWORD is unset. The
    // grafana_reader role's password is (re)set on every boot by
    // R__grafana_reader_password.sql, so a missing env var means we'd either
    // skip the rotation silently or — with a hardcoded fallback — publish a
    // well-known credential for a role with SELECT on audit_log, documents,
    // and transcription_blocks. Same shape as UserDataInitializer's refusal
    // to seed default admin credentials outside dev/test/e2e.
    String resolveGrafanaDbPassword() {
        String value = environment.getProperty("GRAFANA_DB_PASSWORD");
        if (value == null || value.isBlank()) {
            throw new IllegalStateException(
                    "GRAFANA_DB_PASSWORD is required: it is consumed by "
                    + "R__grafana_reader_password.sql to (re)set the grafana_reader "
                    + "role's password on every boot. Generate with: openssl rand -hex 32");
        }
        return value;
    }
}
