"""Basic unit tests for gmailarchiver (no network required)."""

import mailbox
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from gmailarchiver.archive import MboxArchive, MaildirArchive, open_archive
from gmailarchiver.gmail import _MAX_BATCH


# ── archive.py ───────────────────────────────────────────────────────────────

RAW_MSG = b"From: test@example.com\r\nTo: you@example.com\r\nSubject: Test\r\n\r\nHello"


def test_mbox_archive_creates_file(tmp_path):
    path = tmp_path / "test.mbox"
    with MboxArchive(path) as arc:
        arc.add(RAW_MSG)
    assert path.exists()
    mbox = mailbox.mbox(str(path))
    msgs = list(mbox)
    assert len(msgs) == 1


def test_maildir_archive_creates_dir(tmp_path):
    path = tmp_path / "maildir"
    with MaildirArchive(path) as arc:
        arc.add(RAW_MSG)
    assert (path / "cur").exists()
    mdir = mailbox.Maildir(str(path))
    assert len(list(mdir)) == 1


def test_open_archive_factory(tmp_path):
    arc = open_archive("mbox", tmp_path / "out.mbox")
    assert isinstance(arc, MboxArchive)
    arc.close()

    arc = open_archive("maildir", tmp_path / "out")
    assert isinstance(arc, MaildirArchive)
    arc.close()


def test_open_archive_invalid_format(tmp_path):
    with pytest.raises(ValueError, match="Unknown archive format"):
        open_archive("zip", tmp_path / "out.zip")


# ── gmail.py ─────────────────────────────────────────────────────────────────

def test_batch_delete_chunks(monkeypatch):
    """batch_delete must chunk ids into ≤ _MAX_BATCH per call."""
    from gmailarchiver import gmail

    calls = []

    def fake_execute():
        return {}

    def fake_batch_delete(userId, body):
        calls.append(len(body["ids"]))
        m = MagicMock()
        m.execute = fake_execute
        return m

    svc = MagicMock()
    svc.users().messages().batchDelete.side_effect = fake_batch_delete

    ids = [str(i) for i in range(_MAX_BATCH + 50)]
    gmail.batch_delete(svc, ids)

    assert len(calls) == 2
    assert calls[0] == _MAX_BATCH
    assert calls[1] == 50


# ── cli.py ────────────────────────────────────────────────────────────────────

def test_cli_help(capsys):
    from gmailarchiver.cli import build_parser
    p = build_parser()
    with pytest.raises(SystemExit) as exc:
        p.parse_args(["--help"])
    assert exc.value.code == 0


def test_cli_default_output_mbox():
    from gmailarchiver.cli import build_parser
    p = build_parser()
    args = p.parse_args(["2022"])
    # output is None before main() sets the default — that's intentional
    assert args.year == 2022
    assert args.fmt == "mbox"
    assert not args.no_delete
    assert not args.trash
    assert not args.dry_run
