"""CI generator — reads ProjectSpec.ci to generate CI/CD workflows."""

from __future__ import annotations

from pathlib import Path

from jinja2 import Environment, PackageLoader, select_autoescape

from prisme.generators.base import GeneratedFile, GeneratorBase
from prisme.spec.stack import FileStrategy


class CIGenerator(GeneratorBase):
    """Generate CI/CD workflows from ProjectSpec.ci."""

    def generate_files(self) -> list[GeneratedFile]:
        project_spec = self.context.project_spec
        if project_spec is None or project_spec.ci is None:
            return []

        ci = project_spec.ci

        if ci.provider != "github":
            return []

        gen_config = project_spec.generator
        backend_output = Path(gen_config.backend_output)
        frontend_output = Path(gen_config.frontend_output)
        project_dir = Path.cwd()

        backend_path_relative = str(backend_output.parent)
        frontend_path_relative = str(
            frontend_output.parent
            if (project_dir / frontend_output.parent / "package.json").exists()
            else frontend_output
        )
        backend_module = project_spec.backend.module_name or backend_output.name

        env = Environment(
            loader=PackageLoader("prisme", "templates/jinja2"),
            autoescape=select_autoescape(),
            trim_blocks=True,
            lstrip_blocks=True,
        )

        files: list[GeneratedFile] = []

        # CI workflow
        template = env.get_template("ci/github/ci.yml.jinja2")
        content = template.render(
            project_name=project_spec.name,
            project_name_snake=project_spec.name.replace("-", "_"),
            include_frontend=ci.include_frontend,
            use_redis=ci.use_redis,
            python_version="3.13",
            node_version="22",
            enable_codecov=ci.enable_codecov,
            backend_path=backend_path_relative,
            frontend_path=frontend_path_relative,
            backend_module=backend_module,
        )
        files.append(
            GeneratedFile(
                path=Path(".github/workflows/ci.yml"),
                content=content,
                strategy=FileStrategy.GENERATE_ONCE,
                description="CI workflow",
            )
        )

        # Dependabot config
        if ci.enable_dependabot:
            template = env.get_template("ci/github/dependabot.yml.jinja2")
            content = template.render(
                include_frontend=ci.include_frontend,
                github_username=None,
            )
            files.append(
                GeneratedFile(
                    path=Path(".github/dependabot.yml"),
                    content=content,
                    strategy=FileStrategy.GENERATE_ONCE,
                    description="Dependabot config",
                )
            )

        # Semantic release
        if ci.enable_semantic_release:
            template = env.get_template("ci/github/release.yml.jinja2")
            content = template.render(node_version="22")
            files.append(
                GeneratedFile(
                    path=Path(".github/workflows/release.yml"),
                    content=content,
                    strategy=FileStrategy.GENERATE_ONCE,
                    description="Release workflow",
                )
            )

            template = env.get_template("ci/config/releaserc.json.jinja2")
            content = template.render()
            files.append(
                GeneratedFile(
                    path=Path(".releaserc.json"),
                    content=content,
                    strategy=FileStrategy.GENERATE_ONCE,
                    description="Semantic release config",
                )
            )

            # CHANGELOG.md — generate once only
            template = env.get_template("ci/CHANGELOG.md.jinja2")
            content = template.render()
            files.append(
                GeneratedFile(
                    path=Path("CHANGELOG.md"),
                    content=content,
                    strategy=FileStrategy.GENERATE_ONCE,
                    description="Changelog",
                )
            )

        # Commitlint config
        if ci.enable_commitlint:
            template = env.get_template("ci/config/commitlint.config.js.jinja2")
            content = template.render()
            files.append(
                GeneratedFile(
                    path=Path("commitlint.config.js"),
                    content=content,
                    strategy=FileStrategy.GENERATE_ONCE,
                    description="Commitlint config",
                )
            )

        return files
