# 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.context import context
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().filter(scope=context.scope)
        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.filter(scope=context.scope)
        else:
            return Workspace.objects.filter(scope=context.scope, 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
