import math
import numpy as np
import pytest
from startup_app.app import create_app, 숫자정리


class FakeEngine:
    now = [1] * 20
    모델 = {}
    boundary = None
    mid_to_cat = {"커피 전문점": "음식"}
    def 위치확인(self, lat, lon):
        return math.isfinite(lat) and math.isfinite(lon) and 36.4 < lat < 36.7 and 127.1 < lon < 127.4
    def 메타(self):
        return {"업종": {"음식": ["커피 전문점"]}}
    def 분석(self, lat, lon, category):
        return {"업종": category, "count": np.int64(3), "missing": float("nan")}
    def 업종추천(self, lat, lon):
        return {"상태": "표시대상없음", "적은편": [], "많은편": []}


@pytest.fixture
def client():
    return create_app(FakeEngine()).test_client()


@pytest.mark.parametrize("payload", [None, [], 1, "text", {}, {"lat": True, "lon": 127.2}, {"lat": "NaN", "lon": 127.2}, {"lat": 36.5, "lon": "Infinity"}, {"lat": 36.5, "lon": 127.2, "mid": []}, {"lat": 36.5, "lon": 127.2, "mid": {}}, {"lat": 36.5, "lon": 127.2, "mid": "없는 업종"}, {"lat": 37, "lon": 127.2, "mid": "커피 전문점"}])
def test_invalid_requests_are_client_errors(client, payload):
    response = client.post("/api/analyze", json=payload)
    assert response.status_code == 400
    assert "오류" in response.json


def test_valid_request_and_strict_json(client):
    response = client.post("/api/analyze", json={"lat": 36.5, "lon": 127.2, "mid": "커피 전문점"})
    assert response.status_code == 200
    assert response.json == {"업종": "커피 전문점", "count": 3, "missing": None}
    assert "NaN" not in response.text
    assert response.headers["Cache-Control"] == "no-store"


def test_bad_json_and_size_limit(client):
    assert client.post("/api/analyze", data="{", content_type="application/json").status_code == 400
    assert client.post("/api/analyze", data="x" * 17000, content_type="application/json").status_code == 413


def test_pages_and_methods(client):
    assert client.get("/").status_code == 200
    assert client.get("/healthz").json["status"] == "ok"
    assert client.get("/api/meta").json["업종"]["음식"] == ["커피 전문점"]
    assert client.get("/api/analyze").status_code == 405
    assert client.get("/not-here").status_code == 404
    assert client.get("/api/boundary").json["features"] == []
    assert client.post("/api/recommend", json={"lat": 36.5, "lon": 127.2}).json["상태"] == "표시대상없음"


def test_json_cleanup():
    assert 숫자정리({"values": (np.float64("inf"), np.int32(2))}) == {"values": [None, 2]}
