package com.zioinfo.kintex.common.geo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zioinfo.kintex.common.error.ApiException;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * 지오메트리 코덱 단위테스트 — 부스 폴리곤 WKT 조립(링 닫힘 보정)·GeoJSON 파싱·중심 산출.
 * PostGIS ST_GeomFromText 입력 정합성(SRID 0, 미터)을 코드 레벨에서 보증한다.
 */
class GeometryCodecTest {

    private final ObjectMapper mapper = new ObjectMapper();

    @Test
    void toPolygonWkt_closesOpenRing() {
        // 6×3 부스(열린 링) → 닫힌 POLYGON WKT
        List<List<Double>> ring = List.of(
                List.of(0.0, 0.0), List.of(6.0, 0.0), List.of(6.0, 3.0), List.of(0.0, 3.0));
        String wkt = GeometryCodec.toPolygonWkt(ring);
        assertEquals("POLYGON((0 0,6 0,6 3,0 3,0 0))", wkt);
    }

    @Test
    void toPolygonWkt_keepsAlreadyClosedRing() {
        List<List<Double>> ring = List.of(
                List.of(0.0, 0.0), List.of(6.0, 0.0), List.of(6.0, 3.0),
                List.of(0.0, 3.0), List.of(0.0, 0.0));
        assertEquals("POLYGON((0 0,6 0,6 3,0 3,0 0))", GeometryCodec.toPolygonWkt(ring));
    }

    @Test
    void toPolygonWkt_rejectsDegenerateRing() {
        assertThrows(ApiException.class,
                () -> GeometryCodec.toPolygonWkt(List.of(List.of(0.0, 0.0), List.of(1.0, 1.0))));
    }

    @Test
    void parsePolygonRing_readsGeoJsonOuterRing() {
        String geoJson = "{\"type\":\"Polygon\",\"coordinates\":[[[0,0],[6,0],[6,3],[0,3],[0,0]]]}";
        List<List<Double>> ring = GeometryCodec.parsePolygonRing(mapper, geoJson);
        assertEquals(5, ring.size());
        assertEquals(List.of(6.0, 3.0), ring.get(2));
    }

    @Test
    void centroid_returnsArithmeticMean() {
        List<List<Double>> ring = List.of(
                List.of(0.0, 0.0), List.of(6.0, 0.0), List.of(6.0, 3.0), List.of(0.0, 3.0));
        assertEquals(List.of(3.0, 1.5), GeometryCodec.centroid(ring));
    }

    @Test
    void parse_handlesNullAndBlankSafely() {
        assertTrue(GeometryCodec.parsePolygonRing(mapper, null).isEmpty());
        assertTrue(GeometryCodec.parseLineCoords(mapper, "  ").isEmpty());
    }
}
