"""Google Drive logic for the shared jarvis-tools MCP service (Railway).

Same guarantees as the in-process Mac version, but creds come from ENV so it
runs headless on Railway and is reachable by every device:
  DRIVE_SA_JSON    the service-account key JSON (whole file, as one env var)
  DRIVE_FOLDER_ID  the "Jarvis Drive" folder id

A service account has no Drive of its own, so it only sees folders Ahmed shared
with it. Every op below is ALSO folder-jailed to DRIVE_FOLDER_ID as defence in
depth — nothing outside the shared folder is ever touched.

Note: only content ops are exposed remotely (list/read/write/delete). Local
file upload/download live in the Mac in-process tool — a remote server has no
access to a caller's local filesystem.
"""
from __future__ import annotations

import io
import json
import mimetypes
import os

_SCOPES = ["https://www.googleapis.com/auth/drive"]


def _service():
    from google.oauth2 import service_account
    from googleapiclient.discovery import build
    info = json.loads(os.environ["DRIVE_SA_JSON"])
    creds = service_account.Credentials.from_service_account_info(
        info, scopes=_SCOPES)
    return build("drive", "v3", credentials=creds, cache_discovery=False)


def _folder_id() -> str:
    return os.environ["DRIVE_FOLDER_ID"]


def _resolve(svc, ref: str) -> dict | None:
    """Find a file by id or name — ONLY inside the shared folder (jail)."""
    ref = str(ref).strip()
    if not ref:
        return None
    fid = _folder_id()
    try:
        f = svc.files().get(
            fileId=ref, fields="id,name,mimeType,parents").execute()
        return f if fid in (f.get("parents") or []) else None
    except Exception:  # noqa: BLE001 — not an id; fall through to name search
        pass
    q = f"'{fid}' in parents and trashed=false and name='{ref}'"
    files = svc.files().list(q=q, spaces="drive",
                            fields="files(id,name,mimeType)"
                            ).execute().get("files", [])
    return files[0] if files else None


def list_files() -> str:
    svc = _service()
    q = f"'{_folder_id()}' in parents and trashed=false"
    files = svc.files().list(
        q=q, spaces="drive", orderBy="modifiedTime desc",
        fields="files(id,name,mimeType,size,modifiedTime)"
        ).execute().get("files", [])
    if not files:
        return "The shared Jarvis Drive folder is empty."
    lines = []
    for f in files:
        sz = f.get("size")
        sz = f"{int(sz)//1024}KB" if sz else "—"
        lines.append(f"- {f['name']}  ({sz}, {f['modifiedTime'][:10]}) "
                     f"[id {f['id']}]")
    return f"{len(files)} file(s) in Jarvis Drive:\n" + "\n".join(lines)


def read_file(ref: str) -> str:
    svc = _service()
    f = _resolve(svc, ref)
    if not f:
        return "No such file in the shared Jarvis Drive folder."
    mime = f.get("mimeType", "")
    if mime.startswith("application/vnd.google-apps"):
        data = svc.files().export(fileId=f["id"], mimeType="text/plain").execute()
    else:
        data = svc.files().get_media(fileId=f["id"]).execute()
    body = data.decode("utf-8", "ignore") if isinstance(data, bytes) else str(data)
    snip = body[:8000] + (" …[truncated]" if len(body) > 8000 else "")
    return f"{f['name']}:\n{snip}"


def write_file(name: str, content: str) -> str:
    from googleapiclient.http import MediaIoBaseUpload
    name = str(name).strip()
    if not name:
        return "write failed: need a file name."
    svc = _service()
    mime = mimetypes.guess_type(name)[0] or "text/plain"
    media = MediaIoBaseUpload(io.BytesIO(str(content).encode("utf-8")),
                             mimetype=mime, resumable=False)
    existing = _resolve(svc, name)
    if existing and existing.get("name") == name:
        svc.files().update(fileId=existing["id"], media_body=media).execute()
        return f"updated {name} in Jarvis Drive (id {existing['id']})."
    meta = {"name": name, "parents": [_folder_id()]}
    out = svc.files().create(body=meta, media_body=media, fields="id").execute()
    return f"created {name} in Jarvis Drive (id {out['id']})."


def delete_file(ref: str) -> str:
    svc = _service()
    f = _resolve(svc, ref)
    if not f:
        return "No such file in the shared Jarvis Drive folder."
    svc.files().update(fileId=f["id"], body={"trashed": True}).execute()
    return f"Deleted {f['name']} from Jarvis Drive."
