#! python3

"""
Confluence report generation.
"""

import asyncio
import logging
import os

from jinja2 import Environment, ChoiceLoader, FileSystemLoader, PackageLoader

from .config import GlobalConfig
from .connectors import ConfluenceClient
from .metric import Metrics, MetricData
from .utils import fetch_tickets_information

#: Create logger for this file.
logger = logging.getLogger()

#: Object to manipulate the templates.
_jinja_environment: Environment = Environment(
    loader=ChoiceLoader(
        [
            FileSystemLoader(searchpath=os.getcwd()),
            PackageLoader("rate_my_project.metrics"),
        ]
    ),
    autoescape=True,
)


def generate_report(
    confluence_client: ConfluenceClient,
    project_name: str,
    output_space: str,
    output_parent_page: str,
    template: str,
    metric_reports: list,
) -> None:
    """
    Generate the report for the `project_name`.
    The report will be generated on the Confluence `output_space` as a child of
    `output_parent_page`. The page will be generated by taking the given
    `template`.
    The `confluence_client` is used to get the template and publish the report.

    :param confluence_client: Confluence client to publish report.
    :param project_name: Project name.
    :param output_space: Project output Confluence space.
    :param output_parent_page: Project output Confluence parent page.
    :param template: Template page used to render the report.
    :param metric_reports: Data for each metrics needed to generate report.
    """
    logger.debug("Generate report for %s", project_name)

    # Generate report from template
    jinja_template = _jinja_environment.get_template(template)
    content = jinja_template.render(metric_reports=metric_reports)
    report = content.encode("ascii", "ignore").decode()

    # Publish report
    asyncio.run(
        confluence_client.create_or_update_page(
            space=output_space,
            parent_page=output_parent_page,
            title=project_name,
            message=report,
        )
    )

    # Add figures to the report
    for metric_report in metric_reports:
        if metric_report.figures:
            asyncio.run(
                confluence_client.upload_files(
                    space=output_space,
                    title=project_name,
                    filenames=metric_report.figures,
                )
            )

    logger.debug("Report for %s generated", project_name)


def generate_all_reports(global_config: GlobalConfig) -> None:
    """
    Generate all reports given by `global_config`.

    :param global_config: Global configuration.
    """
    logger.info("Generate report on Confluence")

    for project in global_config.config.projects:
        jira_information = asyncio.run(
            fetch_tickets_information(global_config.jira_client(), project.jql)
        )
        metric_data = MetricData.from_tickets_and_changelogs(
            global_config.config.fields.model_dump(),
            project.workflow_to_dict(),
            *jira_information,
        )

        metrics = Metrics(global_config.config.metrics)
        reports = metrics.compute_report(metric_data)

        generate_report(
            global_config.confluence_client(),
            project.name,
            project.report.space,
            project.report.parent_page,
            project.report.template,
            reports,
        )

    logger.info("Report on Confluence generated")
