package incheon.ags.mrb.analysis;

import org.apache.commons.lang3.StringUtils;

import java.util.Locale;

public class AnalysisValidationUtils {

    /**
     * 소스/바운더리 타입 동일성 검사
     * @param srcTy         sourceLayerInfoDTO.getSpceTy()
     * @param bndTy         boundaryLayerInfoDTO.getSpceTy()
     * @param strictExact   문자열 완전 동일 검사 유무
     * @throws IllegalArgumentException 불일치 시
     */
    public static void assertSameGeometryType(String srcTy, String bndTy, boolean strictExact) {
        String srcRaw = StringUtils.defaultString(srcTy);
        String bndRaw = StringUtils.defaultString(bndTy);

        if (strictExact) {
            String s = srcRaw.toUpperCase(Locale.ROOT);
            String b = bndRaw.toUpperCase(Locale.ROOT);
            if (!s.equals(b)) {
                throw new IllegalArgumentException(
                        "소스/경계 레이어의 공간 유형이 일치해야 합니다. " +
                                "source=" + srcRaw + ", boundary=" + bndRaw
                );
            }
        } else {
            String sf = toGeomFamily(srcRaw);
            String bf = toGeomFamily(bndRaw);
            if (!sf.equals(bf)) {
                throw new IllegalArgumentException(
                        "소스/경계 레이어의 공간 유형 계열이 일치해야 합니다. " +
                                "source=" + srcRaw + "(" + sf + "), boundary=" + bndRaw + "(" + bf + ")"
                );
            }
        }
    }

    /**
     * 주어진 공간 유형 문자열을 공간 유형 계열로 정규화한다.
     *
     * @param spceTy 입력 공간 유형 문자열
     * @return "POINT" | "LINESTRING" | "POLYGON" | "GEOMETRY"
     */
    public static String toGeomFamily(String spceTy) {
        String ty = StringUtils.defaultString(spceTy).toUpperCase(Locale.ROOT);
        if (ty.contains("POINT")) return "POINT";
        if (ty.contains("LINESTRING")) return "LINESTRING";
        if (ty.contains("POLYGON")) return "POLYGON";
        return "GEOMETRY";
    }

    /**
     * 클립 가능 여부 검사
     *
     * @param clipperSpceTy  클립 레이어 공간 유형
     * @param targetSpceTy   대상 레이어 공간 유형
     * @throws IllegalArgumentException 규칙 위반 또는 유형 인식 불가 시
     */
    public static void assertClipCompatible(String clipperSpceTy, String targetSpceTy) {
        String clipperFam = toGeomFamily(clipperSpceTy);
        String targetFam  = toGeomFamily(targetSpceTy);

        int clipperRank = geomFamilyRank(clipperFam);
        int targetRank  = geomFamilyRank(targetFam);

        if (clipperRank == 0 || targetRank == 0) {
            throw new IllegalArgumentException(
                    "공간 유형을 인식할 수 없습니다. clipper=" + clipperSpceTy + ", target=" + targetSpceTy
            );
        }
        if (clipperRank < targetRank) {
            throw new IllegalArgumentException(
                    "클립 불가: 클립 유형이 대상 유형보다 낮습니다. " +
                            "규칙: POLYGON ≥ LINESTRING ≥ POINT. " +
                            "clipper=" + clipperSpceTy + "(" + clipperFam + "), target=" + targetSpceTy + "(" + targetFam + ")"
            );
        }
    }

    /**
     * 계열 → 순위 매핑 (POLYGON=3, LINESTRING=2, POINT=1, 기타=0)
     *
     * @param family "POLYGON" | "LINESTRING" | "POINT" | "GEOMETRY"
     * @return 순위 정수 (높을수록 상위)
     */
    public static int geomFamilyRank(String family) {
        return switch (family) {
            case "POLYGON"    -> 3;
            case "LINESTRING" -> 2;
            case "POINT"      -> 1;
            default           -> 0;
        };
    }
}
