# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/jira/classes.ipynb.

# %% ../../nbs/jira/classes.ipynb 2
from __future__ import annotations

from dataclasses import dataclass, field
from typing import List

import datetime as dt
import httpx

from nbdev.showdoc import patch_to

import domolibrary_extensions.jira.auth as ja
import domolibrary_extensions.jira.routes as dejr
import domolibrary_extensions.utils.convert as dxcv

# %% auto 0
__all__ = ['JiraPerson', 'JiraProject', 'JiraPriority', 'JiraComment', 'JiraIssueType', 'JiraRemoteLink', 'JiraIssue']

# %% ../../nbs/jira/classes.ipynb 3
@dataclass
class JiraPerson:
    url: str
    display_name: str
    email_address: str
    avatar_url: str

    @classmethod
    def from_json(cls, obj):
        return cls(
            url=obj["self"],
            display_name=obj["displayName"],
            email_address=obj["emailAddress"],
            avatar_url=obj["avatarUrls"]["48x48"],
        )


@dataclass
class JiraProject:
    uid: str
    id: str
    name: str
    url: str

    @classmethod
    def from_json(cls, obj):
        return cls(uid=obj["id"], id=obj["key"], name=obj["name"], url=obj["self"])


@dataclass
class JiraPriority:
    id: str
    url: str
    title: str

    @classmethod
    def from_json(cls, obj):
        return cls(id=obj["id"], url=obj["self"], title=obj["name"])

# %% ../../nbs/jira/classes.ipynb 4
@dataclass
class JiraComment:
    auth: ja.JiraAuth = field(repr=False)
    jira_author: JiraPerson
    body: str
    created_dt: dt.datetime
    updated_dt: dt.datetime
    rendered_body: str = None

    @classmethod
    def from_json(cls, obj, auth):
        return cls(
            auth=auth,
            jira_author=JiraPerson.from_json(obj["author"]),
            body=obj["body"],
            rendered_body=obj.get("renderedBody"),
            created_dt=dxcv.convert_str_to_date(obj["created"]),
            updated_dt=dxcv.convert_str_to_date(obj["updated"]),
        )

# %% ../../nbs/jira/classes.ipynb 5
@dataclass
class JiraIssueType:
    id: str
    url: str
    description: str

    @classmethod
    def from_json(cls, obj):
        return cls(id=obj["name"], url=obj["self"], description=obj["description"])


@dataclass
class JiraRemoteLink:
    auth: ja.JiraAuth = field(repr=False)
    url: str  # object.url
    title: str  # object.title

    id: str = None  # internal id
    internal_url: str = None  # self
    summary: str = None  # object.summary

    relationship: str = "links to"  # relationship

    global_id: str = None  # globalId, how user identifies entity
    icon_url: str = None  # object.icon.url16x16

    resolved: bool = None  # object.status.resolved
    application_name: str = None  # application.name

    @classmethod
    def from_json(cls, obj, auth):

        return JiraRemoteLink(
            auth=auth,
            id=obj.get("id"),
            internal_url=obj.get("self"),
            global_id=obj.get("globalId"),
            url=obj["object"]["url"],
            title=obj["object"]["title"],
            summary=obj["object"].get("summary"),
            relationship=obj.get("relationship"),
            icon_url=obj["object"].get("icon", {}).get("url16x16"),
            resolved=obj["object"].get("status", {}).get("resolved"),
            application_name=obj["application"].get("name"),
        )

    def to_json(self):
        obj = {
            "globalId": self.global_id,
            "id": self.id,
            "application": {"name": self.application_name},
            "relationship": self.relationship,
            "object": {
                "url": self.url,
                "title": self.title,
                "summary": self.summary,
                "icon": {"url16x16": self.icon_url},
                "status": {"resolved": self.resolved},
            },
            "self": self.internal_url,
        }

        return obj


@dataclass
class JiraIssue:
    auth: ja.JiraAuth = field(repr=False)
    uid: str
    id: str
    title: str
    url: str

    created_dt: dt.datetime
    updated_dt: dt.datetime
    duedate_dt: dt.datetime

    labels: List[str]
    description: str

    jira_status: dict
    # jira_status_category : dict
    jira_issue_type: dict
    jira_priority: JiraPriority
    jira_reporter: JiraPerson
    jira_project: dict

    jira_comments: List[JiraComment]

    jira_links: List[JiraRemoteLink] = None

    @classmethod
    def from_json(cls, obj, auth):

        fields = obj.get("fields")

        return cls(
            auth=auth,
            uid=obj["id"],
            id=obj["key"],
            url=obj["self"],
            title=fields["summary"],
            created_dt=dxcv.convert_str_to_date(fields["created"]),
            duedate_dt=dxcv.convert_str_to_date(fields["duedate"]),
            updated_dt=dxcv.convert_str_to_date(fields["updated"]),
            labels=fields["labels"],
            description=fields["description"],
            jira_status=fields["status"],
            # jira_status_category = fields['statusCategory'],
            jira_issue_type=JiraIssueType.from_json(fields["issuetype"]),
            jira_project=JiraProject.from_json(fields["project"]),
            jira_priority=JiraPriority.from_json(fields["priority"]),
            jira_reporter=JiraPerson.from_json(fields["reporter"]),
            jira_comments=[
                JiraComment.from_json(obj=comment, auth=auth)
                for comment in fields.get("comment", {}).get("comments", [])
            ],
        )

# %% ../../nbs/jira/classes.ipynb 6
@patch_to(JiraIssue, cls_method=True)
async def get_by_id(
    cls,
    issue_id: int,
    auth: ja.JiraAuth,
    debug_api: bool = False,
    return_raw: bool = False,
    is_ignore_cache: bool = False,
    cache_path: str = None,
    client: httpx.AsyncClient = None,
    timeout: int = 30,
):

    res = await dejr.get_issue_by_id(
        auth=auth,
        issue_id=issue_id,
        debug_api=debug_api,
        is_ignore_cache=is_ignore_cache,
        cache_path=cache_path,
        client=client,
        timeout=timeout,
    )

    if return_raw:
        return res

    return cls.from_json(obj=res.response, auth=auth)


@patch_to(JiraIssue)
async def get_comments(
    self,
    debug_api: bool = False,
    return_raw: bool = False,
    is_ignore_cache: bool = False,
    cache_path: str = None,
    client: httpx.AsyncClient = None,
    timeout: int = 30,
):

    res = await dejr.get_issue_comments(
        issue_id=self.id,
        auth=self.auth,
        debug_api=debug_api,
        is_ignore_cache=is_ignore_cache,
        cache_path=cache_path,
        client=client,
        timeout=timeout,
    )

    if return_raw:
        return res

    self.jira_comments = [
        JiraComment.from_json(obj=comment, auth=self.auth) for comment in res.response
    ]

    return self.jira_comments

# %% ../../nbs/jira/classes.ipynb 7
@patch_to(JiraIssue)
async def get_remotelinks(
    self,
    debug_api: bool = False,
    return_raw: bool = False,
    is_ignore_cache: bool = False,
    cache_path: str = None,
    client: httpx.AsyncClient = None,
    timeout: int = 30,
):
    res = await dejr.get_issue_remotelinks(
        auth=self.auth,
        issue_id=self.id,
        debug_api=debug_api,
        is_ignore_cache=is_ignore_cache,
        cache_path=cache_path,
        client=client,
        timeout=timeout,
    )

    if return_raw:
        return res

    self.jira_links = [
        JiraRemoteLink.from_json(link, auth=self.auth) for link in res.response
    ]

    return self.jira_links

# %% ../../nbs/jira/classes.ipynb 8
@patch_to(JiraIssue)
async def upsert_remotelink(
    self,
    remote_link: JiraRemoteLink,
    debug_api: bool = False,
    return_raw: bool = False,
    is_ignore_cache: bool = False,
    cache_path: str = None,
    client: httpx.AsyncClient = None,
    timeout: int = 30,
):
    res = await dejr.upsert_issue_remotelink(
        auth=self.auth,
        issue_id=self.id,
        body=remote_link.to_json(),
        debug_api=debug_api,
        is_ignore_cache=is_ignore_cache,
        cache_path=cache_path,
        client=client,
        timeout=timeout,
    )

    if return_raw:
        return res

    return await self.get_remotelinks()
