# Team Activity Log — Starlark Backend
#
# Handles:
#   GET    /entries          → list (optional ?category= filter)
#   POST   /entries          → create
#   DELETE /entries/:id      → delete
#
# NOTE: The sandbox has no json module. Request body arrives as a raw
# string; response body must be a raw string. Helper functions build
# JSON manually. A json.encode/decode module would clean this up —
# tracked as a sandbox improvement.

def on_request(req):
    method = req["method"]
    path   = req["path"]

    if method == "GET" and path == "/entries":
        return _list_entries(req)
    elif method == "POST" and path == "/entries":
        return _create_entry(req)
    elif method == "DELETE" and path.startswith("/entries/"):
        entry_id = path[len("/entries/"):]
        return _delete_entry(req, entry_id)

    return {"status": 404, "body": '{"error":"not found"}'}


def _list_entries(req):
    category = ""
    q = req.get("query", None)
    if q != None:
        cv = q.get("category", None)
        if cv != None:
            category = str(cv)

    if category:
        rows = db.query("entries", filters={"category": category}, order="-created_at", limit=200)
    else:
        rows = db.query("entries", order="-created_at", limit=200)

    parts = []
    for row in rows:
        parts.append(_entry_json(row))
    return {"status": 200, "body": '{"data":[' + ",".join(parts) + "]}"}


def _create_entry(req):
    body = _parse_body(str(req.get("body", "")))
    if not body:
        return {"status": 400, "body": '{"error":"JSON body required"}'}

    message = body.get("message", "")
    if not message:
        return {"status": 400, "body": '{"error":"message is required"}'}

    category   = body.get("category", "note")
    username   = body.get("username", "")
    created_at = body.get("created_at", "")
    user_id    = str(req.get("user_id", ""))

    # Validate category against admin settings
    allowed = _allowed_categories()
    if allowed and category not in allowed:
        return {"status": 400, "body": '{"error":"invalid category: ' + _esc(category) + '"}'}

    row_id = db.insert("entries", {
        "user_id":    user_id,
        "username":   username,
        "category":   category,
        "message":    message,
        "created_at": created_at,
    })

    _prune()

    return {"status": 201, "body": _entry_json({
        "id": str(row_id), "user_id": user_id, "username": username,
        "category": category, "message": message, "created_at": created_at,
    })}


def _delete_entry(req, entry_id):
    if not entry_id:
        return {"status": 400, "body": '{"error":"entry id required"}'}
    db.delete("entries", entry_id)
    return {"status": 200, "body": '{"deleted":true,"id":"' + _esc(entry_id) + '"}'}


# ── Settings helpers ─────────────────────────

def _allowed_categories():
    raw = settings.get("categories")
    if not raw:
        return []
    return [p.strip() for p in raw.split(",") if p.strip()]


def _prune():
    max_raw = settings.get("max_entries")
    if not max_raw:
        return
    limit = int(max_raw)
    if limit <= 0:
        return
    rows = db.query("entries", order="-created_at", limit=limit + 50)
    if len(rows) > limit:
        for row in rows[limit:]:
            db.delete("entries", row["id"])


# ── JSON helpers (no json module in sandbox) ─

def _esc(s):
    return str(s).replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")

def _entry_json(e):
    return (
        '{"id":"'          + _esc(e.get("id", ""))
      + '","user_id":"'    + _esc(e.get("user_id", ""))
      + '","username":"'   + _esc(e.get("username", ""))
      + '","category":"'   + _esc(e.get("category", ""))
      + '","message":"'    + _esc(e.get("message", ""))
      + '","created_at":"' + _esc(e.get("created_at", ""))
      + '"}'
    )

def _parse_body(raw):
    """Minimal flat-object JSON parser. Handles {"key":"value"} payloads."""
    s = raw.strip()
    if not s or s[0] != "{":
        return None
    s = s[1:]
    if s and s[-1] == "}":
        s = s[:-1]

    result = {}
    in_str = False
    escape = False
    current = ""
    pairs = []

    for ch in s.elems():
        if escape:
            current += ch
            escape = False
        elif ch == "\\":
            current += ch
            escape = True
        elif ch == '"':
            current += ch
            in_str = not in_str
        elif ch == "," and not in_str:
            pairs.append(current.strip())
            current = ""
        else:
            current += ch
    if current.strip():
        pairs.append(current.strip())

    for pair in pairs:
        colon = -1
        in_s = False
        esc = False
        for i in range(len(pair)):
            c = pair[i]
            if esc:
                esc = False
            elif c == "\\":
                esc = True
            elif c == '"':
                in_s = not in_s
            elif c == ":" and not in_s:
                colon = i
                break
        if colon < 0:
            continue
        key = _unquote(pair[:colon].strip())
        val = _unquote(pair[colon+1:].strip())
        if key:
            result[key] = val
    return result

def _unquote(s):
    if len(s) >= 2 and s[0] == '"' and s[-1] == '"':
        return s[1:-1].replace('\\"', '"').replace("\\\\", "\\").replace("\\n", "\n")
    return s
