# Copyright (c) 2024 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com

from typing import Any

from pulumi import Output
from pulumi_sumologic import (
    ContentPermission,
    ContentPermissionPermissionArgs,
    Folder,
    MonitorFolder,
    MonitorFolderObjPermissionArgs,
    get_role,
)
from pydantic import BaseModel, Field, root_validator

from czpulumi.sumo_logic.models import ConfiguredBaseModel
from czpulumi.sumo_logic.roles import ObjectPermissionLevel, SumoPermissionScope, SumoRole
from czpulumi.sumo_logic.sumo_client import get_sumo_client


class FolderPermission(ConfiguredBaseModel):
    role: SumoRole = Field(..., description='The role to assign the permission to')
    scopes: list[SumoPermissionScope] = Field(default_factory=list, description='The permission scopes to assign to the role')


class MonitorFolderPermission(ConfiguredBaseModel):
    role: SumoRole = Field(..., description='The role to assign the permission to')
    permissions: list[ObjectPermissionLevel] = Field(
        default_factory=list, description='The permission levels to assign to the role'
    )


def apply_folder_permissions(content_id: Output, permissions: list[FolderPermission] | None = None):
    permissions = permissions or []
    content_permissions: list[ContentPermissionPermissionArgs] = []
    permissions.extend(
        [
            FolderPermission(
                role=SumoRole.TEAM_ENGINEERING_DEVELOPER_EXPERIENCE,
                scopes=[SumoPermissionScope.VIEW, SumoPermissionScope.EDIT, SumoPermissionScope.MANAGE],
            ),
            FolderPermission(
                role=SumoRole.TEAM_OCTO,
                scopes=[SumoPermissionScope.VIEW, SumoPermissionScope.EDIT, SumoPermissionScope.MANAGE],
            ),
            FolderPermission(
                role=SumoRole.ADMINISTRATOR,
                scopes=[SumoPermissionScope.VIEW, SumoPermissionScope.EDIT, SumoPermissionScope.MANAGE],
            ),
        ]
    )
    for permission in permissions:
        for scope in permission.scopes:
            content_permissions.append(
                ContentPermissionPermissionArgs(
                    permission_name=scope,
                    source_type='role',
                    source_id=get_role(name=permission.role).id,
                )
            )

    content_id.apply(
        lambda folder_id: ContentPermission(
            resource_name=f'folder_{folder_id}_permissions',
            content_id=folder_id,
            notify_recipient=False,
            permissions=content_permissions,
        )
    )


class BaseFolder(BaseModel):
    class Config:
        arbitrary_types_allowed = True

    name: str = Field(..., description='The name of the folder')
    title: str = Field(..., description='The title of the folder')
    description: str = Field(..., description='The description of the folder')
    permissions: list[FolderPermission] = Field(default_factory=list, description='The permissions to assign to the folder')
    parent_folder_id: Any = Field(..., description='The ID of the parent folder')
    folder: Folder

    @root_validator(pre=True)
    def create_folder(cls, values):
        values['folder'] = Folder(
            resource_name=f"folder_{values['name']}",
            description=values['description'],
            parent_id=values['parent_folder_id'],
            name=values['title'],
        )
        apply_folder_permissions(values['folder'].id, values.get('permissions', []))
        return values


class BaseMonitorFolder(BaseModel):
    class Config:
        arbitrary_types_allowed = True

    name: str = Field(..., description='The name of the folder')
    title: str = Field(..., description='The title of the folder')
    description: str = Field(..., description='The description of the folder')
    permissions: list[MonitorFolderPermission] = Field(
        default_factory=list, description='The permissions to assign to the folder'
    )
    parent_folder_id: Any = Field(None, description='The ID of the parent folder')
    folder: MonitorFolder

    @root_validator(pre=True)
    def create_folder(cls, values):
        MonitorFolderObjPermissionArgs
        values['folder'] = MonitorFolder(
            resource_name=f"monitor_folder_{values['name']}",
            description=values['description'],
            parent_id=values.get('parent_folder_id', None),
            # TODO: Enable this once Sumo Logic support responds with why permissions are not working
            # obj_permissions=cls._get_permissions(values.get("permissions", [])), # noqa: ERA001
            name=values['title'],
        )
        return values

    @staticmethod
    def _get_permissions(permissions: list[MonitorFolderPermission]):
        object_permissions = []
        role_ids = {}
        for permission in permissions:
            if permission.role not in role_ids:
                role_ids[permission.role] = get_role(name=permission.role).id
            object_permissions.append(
                MonitorFolderObjPermissionArgs(
                    permissions=permission.permissions, subject_id=role_ids[permission.role], subject_type='role'
                )
            )
        return object_permissions


def get_personal_folder() -> dict:
    client = get_sumo_client()
    return client.get_personal_folder().json()


def get_folder(folder_id: str) -> dict:
    client = get_sumo_client()
    return client.get(f'/content/folders/{folder_id}', version='v2').json()


def update_folder(folder_id: str, body: dict) -> dict:
    client = get_sumo_client()
    return client.put(f'/content/folders/{folder_id}', body, version='v2').json()
