# Copyright 2024 The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""debusine workspace views."""

from django.db.models import Count
from django.http import Http404

from debusine.db.models import Collection, Workspace
from debusine.web.views.base import BaseUIView, DetailViewBase, ListViewBase


class WorkspaceListView(BaseUIView, ListViewBase[Workspace]):
    """List workspaces."""

    model = Workspace
    template_name = "web/workspace-list.html"
    context_object_name = "workspace_list"
    ordering = "name"

    def get_queryset(self):
        """All workspaces for authenticated users or only public ones."""
        queryset = super().get_queryset()
        if not self.request.user.is_authenticated:
            queryset = queryset.filter(public=True)
        return queryset


class WorkspaceDetailView(BaseUIView, DetailViewBase[Workspace]):
    """Show a workspace detail."""

    model = Workspace
    template_name = "web/workspace-detail.html"
    context_object_name = "workspace"

    def get_object(self, queryset=None) -> Workspace:
        """Return the workspace object to show."""
        if queryset is None:
            queryset = self.get_queryset()  # pragma: no cover
        try:
            return queryset.get(name=self.kwargs["wname"])
        except queryset.model.DoesNotExist:
            raise Http404(f"Workspace {self.kwargs['wname']} not found")

    def get_queryset(self):
        """All workspaces for authenticated users or only public ones."""
        if self.request.user.is_authenticated:
            return Workspace.objects.all()
        else:
            return Workspace.objects.filter(public=True)

    def get_workspace(self) -> Workspace:
        """Return the current workspace."""
        return self.object

    def get_title(self) -> str:
        """Return the page title."""
        return f"Workspace {self.object.name}"

    def get_context_data(self, *args, **kwargs):
        """Return context for this view."""
        context = super().get_context_data(*args, **kwargs)

        # Collections grouped by category
        stats = list(
            Collection.objects.filter(workspace=self.object)
            .exclude(category="debusine:workflow-internal")
            .values("category")
            .annotate(count=Count("category"))
            .order_by("category")
        )
        context["collection_stats"] = stats
        context["collection_count"] = sum(s["count"] for s in stats)

        return context
