# 엘리베이터 촬영앱 OTA 보관소 서버 (A컴 상주)
# - /app.html      : 최신 앱 본체 (자립형 단일 HTML)
# - /version.json  : {"build":N,"name":..,"date":..,"notes":..}
# - /checkin?device=..&ver=..  : 설치기기 체크인 로그 기록
# - /stats         : 설치 대수/버전 요약 (브라우저로 확인용)
import http.server, socketserver, os, urllib.parse, datetime, json, threading

ROOT = os.path.dirname(os.path.abspath(__file__))
LOG  = os.path.join(ROOT, 'checkins.log')
PORT = 8098
lock = threading.Lock()

class H(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **k):
        super().__init__(*a, directory=ROOT, **k)

    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Cache-Control', 'no-store')
        super().end_headers()

    def _text(self, code, body):
        b = body.encode('utf-8')
        self.send_response(code)
        self.send_header('Content-Type', 'text/plain; charset=utf-8')
        self.send_header('Content-Length', str(len(b)))
        self.end_headers()
        self.wfile.write(b)

    def do_GET(self):
        u = urllib.parse.urlparse(self.path)
        if u.path == '/checkin':
            q = urllib.parse.parse_qs(u.query)
            dev = (q.get('device', ['?'])[0])[:64]
            ver = (q.get('ver', ['?'])[0])[:32]
            ua  = (self.headers.get('User-Agent', ''))[:140]
            line = "\t".join([datetime.datetime.now().isoformat(timespec='seconds'),
                              self.client_address[0], dev, ver, ua]) + "\n"
            with lock:
                with open(LOG, 'a', encoding='utf-8') as f:
                    f.write(line)
            return self._text(200, 'ok')
        if u.path == '/stats':
            return self._text(200, self._stats())
        return super().do_GET()

    def _stats(self):
        if not os.path.exists(LOG):
            return 'no checkins yet'
        seen = {}          # device -> (last_ts, ver)
        total = 0
        with open(LOG, encoding='utf-8') as f:
            for ln in f:
                p = ln.rstrip('\n').split('\t')
                if len(p) < 4:
                    continue
                total += 1
                ts, ip, dev, ver = p[0], p[1], p[2], p[3]
                seen[dev] = (ts, ver)
        out = [f"# 설치 기기: {len(seen)}대   (총 체크인 {total}회)", ""]
        for dev, (ts, ver) in sorted(seen.items(), key=lambda x: x[1][0], reverse=True):
            out.append(f"{ts}   v{ver}   {dev}")
        return "\n".join(out)

    def log_message(self, *a):
        pass

socketserver.ThreadingTCPServer.allow_reuse_address = True
with socketserver.ThreadingTCPServer(('0.0.0.0', PORT), H) as httpd:
    print(f"elevota serving {ROOT} on :{PORT}")
    httpd.serve_forever()
