package com.lingniu.ingest.historyapp;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

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

class WoodpeckerPipelineTest {

    @Test
    void dockerPublishUsesOneProductionAppList() throws IOException {
        String pipeline = Files.readString(repositoryRoot().resolve("woodpecker.yml"));

        assertThat(pipeline)
                .contains("ACTIVE_APPS: &active_apps \"gb32960-ingest-app jt808-ingest-app yutong-mqtt-app vehicle-history-app vehicle-analytics-app\"")
                .contains("ACTIVE_APPS: *active_apps")
                .contains("- name: docker-build-apps")
                .doesNotContain("xinda-push-app")
                .doesNotContain("KAFKA_TOPIC_XINDA_PUSH");

        assertThat(countOccurrences(pipeline, "- name: docker-build-")).isEqualTo(1);
    }

    @Test
    void activeAppListIsDefinedOnceAndReusedAcrossPipelineSteps() throws IOException {
        String pipeline = Files.readString(repositoryRoot().resolve("woodpecker.yml"));
        String activeApps = "gb32960-ingest-app jt808-ingest-app yutong-mqtt-app vehicle-history-app vehicle-analytics-app";

        assertThat(countOccurrences(pipeline, activeApps)).isEqualTo(1);
        assertThat(pipeline)
                .contains("ACTIVE_APPS: &active_apps \"" + activeApps + "\"")
                .contains("ACTIVE_APPS: *active_apps")
                .doesNotContain("ACTIVE_APPS=\"" + activeApps + "\"");
    }

    @Test
    void mavenBuildSkipsTestExecutionAndCompilationInCi() throws IOException {
        String pipeline = Files.readString(repositoryRoot().resolve("woodpecker.yml"));

        assertThat(pipeline)
                .contains("mvn -B -ntp -am -pl \"$ACTIVE_MODULES\" package -Dmaven.test.skip=true")
                .doesNotContain("-DskipTests");
    }

    @Test
    void dockerPublishUsesOverridableImagePrefix() throws IOException {
        String pipeline = Files.readString(repositoryRoot().resolve("woodpecker.yml"));

        assertThat(pipeline)
                .contains("REGISTRY=${LINGNIU_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}")
                .contains("NAMESPACE=${LINGNIU_IMAGE_NAMESPACE:-oneos}")
                .contains("IMAGE=$REGISTRY/$NAMESPACE/$APP_NAME:$APP_VERSION")
                .doesNotContain("\n      REGISTRY=crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com")
                .doesNotContain("\n      NAMESPACE=oneos");
    }

    @Test
    void dockerImageExposesOnlyCurrentProductionPorts() throws IOException {
        String dockerfile = Files.readString(repositoryRoot().resolve("Dockerfile"));

        assertThat(dockerfile)
                .contains("EXPOSE 20100 20200 20300 20400 20500 32960 808")
                .doesNotContain("10808")
                .doesNotContain("8089");
    }

    private static int countOccurrences(String value, String needle) {
        int count = 0;
        int from = 0;
        while (true) {
            int next = value.indexOf(needle, from);
            if (next < 0) {
                return count;
            }
            count++;
            from = next + needle.length();
        }
    }

    private static Path repositoryRoot() {
        Path current = Path.of(System.getProperty("user.dir")).toAbsolutePath();
        while (current != null) {
            if (Files.exists(current.resolve("woodpecker.yml"))) {
                return current;
            }
            current = current.getParent();
        }
        throw new IllegalStateException("repository root not found");
    }
}
