package incheon.product.common.config;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

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

/**
 * GeoViewProperties 기본값 보호(회귀) 테스트.
 * 기본값이 실수로 변경되는 것을 방어한다.
 */
class GeoViewPropertiesTest {

    private final GeoViewProperties props = new GeoViewProperties();

    @Test
    @DisplayName("GisServer 기본값이 유지된다")
    void gisServerDefaults() {
        GeoViewProperties.GisServer gs = props.getGisServer();
        assertThat(gs.getWorkspace()).isEqualTo("incheon");
        assertThat(gs.getStorage()).isEqualTo("iccom");
        assertThat(gs.getSyncWaitMillis()).isEqualTo(3000L);
        assertThat(gs.getUrl()).isNull();
    }

    @Test
    @DisplayName("BoundingBox 기본값 — 인천 영역 범위가 유지된다")
    void fallbackBboxDefaults() {
        GeoViewProperties.BoundingBox bbox = props.getGisServer().getFallbackBbox();
        assertThat(bbox.getMinx()).isCloseTo(746110.26, within(1.0));
        assertThat(bbox.getMiny()).isCloseTo(1881540.25, within(1.0));
        assertThat(bbox.getMaxx()).isCloseTo(937637.28, within(1.0));
        assertThat(bbox.getMaxy()).isCloseTo(2001987.24, within(1.0));
    }

    @Test
    @DisplayName("Coordinate 기본값 — EPSG:5181/3857이 유지된다")
    void coordinateDefaults() {
        GeoViewProperties.Coordinate coord = props.getCoordinate();
        assertThat(coord.getDefaultSrid()).isEqualTo(5181);
        assertThat(coord.getServiceSrid()).isEqualTo(3857);
    }

    @Test
    @DisplayName("Layer 기본값이 유지된다")
    void layerDefaults() {
        GeoViewProperties.Layer layer = props.getLayer();
        assertThat(layer.getServicePrefix()).isEqualTo("incheon");
        assertThat(layer.getImageMaxSize()).isEqualTo(4000);
        assertThat(layer.getImageDefaultSize()).isEqualTo(1920);
        assertThat(layer.getBatchChunkSize()).isEqualTo(1000);
    }

    @Test
    @DisplayName("Download 기본값이 유지된다")
    void downloadDefaults() {
        GeoViewProperties.Download dl = props.getDownload();
        assertThat(dl.getExcelMaxRows()).isEqualTo(100000);
        assertThat(dl.getStreamingFetchSize()).isEqualTo(10000);
    }

    @Test
    @DisplayName("중첩 객체가 null이 아니다")
    void nestedObjectsNotNull() {
        assertThat(props.getGisServer()).isNotNull();
        assertThat(props.getGisServer().getFallbackBbox()).isNotNull();
        assertThat(props.getCoordinate()).isNotNull();
        assertThat(props.getLayer()).isNotNull();
        assertThat(props.getDownload()).isNotNull();
    }

    @Test
    @DisplayName("Setter로 값을 변경할 수 있다")
    void setterWorks() {
        GeoViewProperties.GisServer gs = props.getGisServer();
        gs.setUrl("http://test:8080");
        assertThat(gs.getUrl()).isEqualTo("http://test:8080");

        GeoViewProperties.Coordinate coord = props.getCoordinate();
        coord.setDefaultSrid(4326);
        assertThat(coord.getDefaultSrid()).isEqualTo(4326);
    }
}
