#!/usr/bin/env python3
"""ASUCB Learnings Logger — structured per-course operational learnings."""

import argparse
import json
import logging
import os
import sys
from datetime import datetime, timezone

sys.path.insert(0, os.path.dirname(__file__))
from canvas_api import get_plugin_root


VALID_CATEGORIES = [
    "program-specific-template-deviations",
    "faculty-naming-conventions",
    "tool-restrictions",
    "recurring-review-issues",
    "known-course-quirks",
]


def _learnings_path(course_id):
    """Return courses/{courseId}/learnings.jsonl, creating parent dirs."""
    course_dir = os.path.join(get_plugin_root(), "courses", str(course_id))
    os.makedirs(course_dir, exist_ok=True)
    return os.path.join(course_dir, "learnings.jsonl")


def _now_iso():
    """Return current UTC time as ISO 8601 Zulu."""
    return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")


def _read_jsonl(path):
    """Read JSONL records from a file, skipping malformed lines."""
    if not os.path.exists(path):
        return []

    records = []
    try:
        with open(path, "r", encoding="utf-8") as f:
            for line_num, line in enumerate(f, start=1):
                line = line.strip()
                if not line:
                    continue
                try:
                    records.append(json.loads(line))
                except json.JSONDecodeError as exc:
                    logging.warning(
                        "Failed to parse learning record at %s:%s: %s",
                        path, line_num, exc,
                    )
    except OSError as exc:
        logging.warning("Failed to read learnings for course %s: %s", path, exc)
        return []
    return records


def append_learning(course_id, category, note):
    """Append a structured learning record to learnings.jsonl."""
    if category not in VALID_CATEGORIES:
        return {"ok": False, "error": f"Invalid category: {category}"}

    learning = {
        "timestamp": _now_iso(),
        "category": category,
        "note": note,
        "course_id": str(course_id),
        "promoted_at": None,
    }

    path = _learnings_path(course_id)
    try:
        with open(path, "a", encoding="utf-8") as f:
            f.write(json.dumps(learning, ensure_ascii=False) + "\n")
    except OSError as exc:
        logging.warning(
            "Failed to append learning for course %s: %s", course_id, exc
        )
        return {"ok": False, "error": str(exc), "learning": learning}

    return {"ok": True, "path": path, "learning": learning}


def list_learnings(course_id):
    """Return all learning records for a course."""
    return _read_jsonl(_learnings_path(course_id))


def search_learnings(course_id, category):
    """Return learning records matching an allowed category."""
    if category not in VALID_CATEGORIES:
        return []
    return [r for r in list_learnings(course_id) if r.get("category") == category]


def main():
    parser = argparse.ArgumentParser(description="ASUCB Learnings Logger")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--append", action="store_true", help="Append a learning")
    group.add_argument("--list", action="store_true", help="List learnings")
    group.add_argument("--search", action="store_true", help="Search learnings")

    parser.add_argument("--course-id", help="Canvas course ID")
    parser.add_argument("--category", choices=VALID_CATEGORIES,
                        help="Learning category")
    parser.add_argument("--note", help="Learning note text")

    args = parser.parse_args()

    if args.append:
        if not args.course_id or not args.category or args.note is None:
            parser.error("--append requires --course-id, --category, and --note")
        print(json.dumps(
            append_learning(args.course_id, args.category, args.note),
            indent=2,
        ))

    elif args.list:
        if not args.course_id:
            parser.error("--list requires --course-id")
        print(json.dumps({
            "ok": True,
            "learnings": list_learnings(args.course_id),
        }, indent=2))

    elif args.search:
        if not args.course_id or not args.category:
            parser.error("--search requires --course-id and --category")
        print(json.dumps({
            "ok": True,
            "learnings": search_learnings(args.course_id, args.category),
        }, indent=2))


if __name__ == "__main__":
    main()
