# Copyright 2025 Softwell S.r.l.
# Licensed under the Apache License, Version 2.0

"""Auth Demo - Example app for testing tag-based authorization.

Structure:
    AuthDemo (root)
    ├── public/              → no auth required
    │   ├── welcome
    │   └── info
    ├── staff/               → requires "staff"
    │   ├── dashboard        → staff
    │   ├── profile          → staff
    │   └── confidential     → staff&senior (senior staff only)
    ├── management/          → requires "manager"
    │   ├── reports/         → manager
    │   │   ├── sales        → manager
    │   │   └── budget       → manager&finance (manager with finance access)
    │   └── team/            → manager
    │       ├── list         → manager
    │       └── hire         → manager&hr (manager with hr access)
    ├── hr/                  → requires "hr"
    │   ├── employees        → hr
    │   ├── salaries         → hr&senior (sensitive data)
    │   └── resigned         → hr&!intern (hr but not intern)
    ├── admin/               → requires "admin"
    │   ├── users            → admin
    │   ├── settings         → admin&senior
    │   └── audit            → admin&(senior|security) (admin with senior OR security)
    └── special/             → complex rules
        ├── cross_dept       → manager|hr (manager OR hr)
        ├── leadership       → (manager|director)&!intern
        └── restricted       → admin&senior&!resigned

Run: python -m genro_asgi serve examples/auth_demo

Test tokens (see config.yaml):
    tk_guest      → guest
    tk_staff      → staff
    tk_senior     → staff,senior
    tk_manager    → staff,manager
    tk_hr         → staff,hr
    tk_hr_senior  → staff,hr,senior
    tk_admin      → staff,admin,senior
    tk_intern     → staff,hr,intern
    tk_resigned   → staff,resigned
"""

from genro_routes import Router, RoutingClass, route

from genro_asgi import AsgiApplication

# Note: AuthDemo uses AsgiApplication which provides self.main_router via super().__init__()
# Sub-areas use RoutingClass with their own routers


class PublicArea(RoutingClass):
    """Public area - no authentication required."""

    def __init__(self):
        self.api = Router(self, name="api")

    @route("api")
    def welcome(self):
        return "Public: Welcome to Auth Demo - no auth required"

    @route("api")
    def info(self):
        return "Public: Company info - accessible to everyone"


class StaffArea(RoutingClass):
    """Staff area - requires 'staff' tag."""

    def __init__(self):
        self.api = Router(self, name="api").plug("auth", tags="staff")

    @route("api")
    def dashboard(self):
        return "Staff: Dashboard [requires: staff]"

    @route("api")
    def profile(self):
        return "Staff: Your profile [requires: staff]"

    @route("api", auth_tags="senior")
    def confidential(self):
        return "Staff: Confidential info [requires: staff&senior]"


class ReportsSection(RoutingClass):
    """Reports section within management."""

    def __init__(self):
        self.api = Router(self, name="api")

    @route("api")
    def sales(self):
        return "Management/Reports: Sales report [requires: manager]"

    @route("api", auth_tags="finance")
    def budget(self):
        return "Management/Reports: Budget report [requires: manager&finance]"


class TeamSection(RoutingClass):
    """Team section within management."""

    def __init__(self):
        self.api = Router(self, name="api")

    @route("api")
    def list(self):
        return "Management/Team: Team members [requires: manager]"

    @route("api", auth_tags="hr")
    def hire(self):
        return "Management/Team: Hire new member [requires: manager&hr]"


class ManagementArea(RoutingClass):
    """Management area - requires 'manager' tag."""

    def __init__(self):
        self.api = Router(self, name="api").plug("auth", tags="manager")
        self.reports = ReportsSection()
        self.team = TeamSection()


class HRArea(RoutingClass):
    """HR area - requires 'hr' tag with special cases."""

    def __init__(self):
        self.api = Router(self, name="api").plug("auth", tags="hr")

    @route("api")
    def employees(self):
        return "HR: Employee directory [requires: hr]"

    @route("api", auth_tags="senior")
    def salaries(self):
        return "HR: Salary information [requires: hr&senior]"

    @route("api", auth_tags="!intern")
    def resigned(self):
        return "HR: Resigned employees [requires: hr&!intern]"


class AdminArea(RoutingClass):
    """Admin area - requires 'admin' tag with complex rules."""

    def __init__(self):
        self.api = Router(self, name="api").plug("auth", tags="admin")

    @route("api")
    def users(self):
        return "Admin: User management [requires: admin]"

    @route("api", auth_tags="senior")
    def settings(self):
        return "Admin: System settings [requires: admin&senior]"

    @route("api", auth_tags="senior|security")
    def audit(self):
        return "Admin: Audit log [requires: admin&(senior|security)]"


class SpecialArea(RoutingClass):
    """Special area - complex tag rules."""

    def __init__(self):
        self.api = Router(self, name="api").plug("auth")

    @route("api", auth_tags="manager|hr")
    def cross_dept(self):
        return "Special: Cross-department access [requires: manager|hr]"

    @route("api", auth_tags="(manager|director)&!intern")
    def leadership(self):
        return "Special: Leadership only [requires: (manager|director)&!intern]"

    @route("api", auth_tags="admin&senior&!resigned")
    def restricted(self):
        return "Special: Highly restricted [requires: admin&senior&!resigned]"


class Application(AsgiApplication):
    """Root application demonstrating tag-based authorization."""

    openapi_info = {
        "title": "Auth Demo API",
        "version": "1.0.0",
        "description": "Example API demonstrating tag-based authorization",
    }

    def __init__(self):
        super().__init__()
        self.public = PublicArea()
        self.staff = StaffArea()
        self.management = ManagementArea()
        self.hr = HRArea()
        self.admin = AdminArea()
        self.special = SpecialArea()

    @route()
    def index(self):
        return "Auth Demo: /public, /staff, /management, /hr, /admin, /special"


if __name__ == "__main__":
    demo = Application()
    print("AuthDemo structure:")
    print(demo.routing)
