"""Artifacts export - zip source at a given revision SHA.

For MVP: source.zip export for React, Nuxt, HTML projects.
Shopify/WordPress theme exports deferred.
"""
from __future__ import annotations
import io
from typing import Optional
import os
import tempfile
import zipfile

import structlog

logger = structlog.get_logger()


class ArtifactService:
    """Export project source code as downloadable archives."""

    async def export_source_zip(self, repo_path: str, revision_label: Optional[str] = None) -> bytes:
        """Create a zip archive of the repo at the given path."""
        buf = io.BytesIO()
        with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zf:
            for root, dirs, files in os.walk(repo_path):
                dirs[:] = [d for d in dirs if d not in ("node_modules", ".git", ".venv", "__pycache__")]
                for fname in files:
                    fpath = os.path.join(root, fname)
                    arcname = os.path.relpath(fpath, repo_path)
                    zf.write(fpath, arcname)

        buf.seek(0)
        logger.info("artifact_source_zip_created", repo_path=repo_path, size=buf.getbuffer().nbytes)
        return buf.read()
