package at.procon.dip.architecture;

import at.procon.dip.domain.ted.config.TedProjectionProperties;
import at.procon.dip.ingestion.config.DipIngestionProperties;
import at.procon.dip.domain.time.config.TimeDomainProperties;
import at.procon.dip.search.config.DipSearchProperties;
import at.procon.ted.config.TedProcessorProperties;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;
import org.junit.jupiter.api.Test;

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

/**
 * Regression guard for the runtime/config split.
 * NEW runtime classes must not depend on TedProcessorProperties anymore.
 */
class NewRuntimeMustNotDependOnTedProcessorPropertiesTest {

    @Test
    void new_runtime_classes_should_not_depend_on_ted_processor_properties() {
        List<Class<?>> newRuntimeClasses = List.of(
                at.procon.dip.ingestion.service.GenericDocumentImportService.class,
                at.procon.dip.ingestion.camel.GenericFileSystemIngestionRoute.class,
                at.procon.dip.ingestion.controller.GenericDocumentImportController.class,
                at.procon.dip.ingestion.adapter.MailDocumentIngestionAdapter.class,
                at.procon.dip.ingestion.adapter.TedPackageDocumentIngestionAdapter.class,
                at.procon.dip.ingestion.service.TedPackageChildImportProcessor.class,
                at.procon.dip.domain.ted.service.TedNoticeProjectionService.class,
                at.procon.dip.domain.ted.startup.TedProjectionStartupRunner.class,
                at.procon.dip.search.engine.fulltext.PostgresFullTextSearchEngine.class,
                at.procon.dip.search.engine.trigram.PostgresTrigramSearchEngine.class,
                at.procon.dip.search.engine.semantic.PgVectorSemanticSearchEngine.class,
                at.procon.dip.search.rank.DefaultSearchResultFusionService.class,
                at.procon.dip.search.service.DefaultSearchOrchestrator.class,
                at.procon.dip.search.service.SearchLexicalIndexStartupRunner.class,
                at.procon.dip.normalization.impl.ChunkedLongTextRepresentationBuilder.class
        );

        for (Class<?> type : newRuntimeClasses) {
            assertThat(hasDependency(type, TedProcessorProperties.class))
                    .as(type.getName() + " must not depend on TedProcessorProperties")
                    .isFalse();
        }
    }

    @Test
    void new_runtime_config_classes_exist_as_replacements() {
        assertThat(DipSearchProperties.class).isNotNull();
        assertThat(DipIngestionProperties.class).isNotNull();
        assertThat(TedProjectionProperties.class).isNotNull();
        assertThat(TimeDomainProperties.class).isNotNull();
    }

    private boolean hasDependency(Class<?> owner, Class<?> dependency) {
        for (Field field : owner.getDeclaredFields()) {
            if (field.getType().equals(dependency)) {
                return true;
            }
        }
        for (Constructor<?> constructor : owner.getDeclaredConstructors()) {
            for (Class<?> param : constructor.getParameterTypes()) {
                if (param.equals(dependency)) {
                    return true;
                }
            }
        }
        return false;
    }
}