from __future__ import annotations

import argparse
from dataclasses import dataclass
from pathlib import Path

import nox
from nox import Session

from exasol.toolbox.metrics import (
    Format,
    create_report,
    format_report,
)
from noxconfig import PROJECT_CONFIG


@dataclass
class RequiredFile:
    """
    Describes a required file and the related nox task to generate this
    file.
    """

    def __init__(self, file: Path | str, task: str):
        self.file = file if isinstance(file, Path) else PROJECT_CONFIG.root / file
        self.task = task

    def __str__(self) -> str:
        return f"{self.file.name} generated by `{self.task}`"


@nox.session(name="project:report", python=False)
def report(session: Session) -> None:
    """
    Collects and generates metrics summary for the workspace

    Attention:

        Pre-requisites:

        * Make sure you remove old and outdated artifacts
            - e.g. by running one of the following commands
                * :code:`git clean -xdf`
                * :code:`rm .coverage .lint.txt`

        * Run the following targets:
            - :code:`nox -s test:coverage`
            - :code:`nox -s lint:code`
            - :code:`nox -s lint:security`
    """
    formats = tuple(fmt.name.lower() for fmt in Format)
    usage = "nox -s project:report -- [options]"
    parser = argparse.ArgumentParser(
        description="Generates status report for the project", usage=usage
    )
    parser.add_argument(
        "-f",
        "--format",
        type=str,
        default=formats[0],
        help="Output format to produce.",
        choices=formats,
    )
    required_files = [
        RequiredFile(".coverage", "test:coverage"),
        RequiredFile(".lint.txt", "lint:code"),
        RequiredFile(".security.json", "lint:security"),
    ]
    if missing_files := [f for f in required_files if not f.file.exists()]:
        missing = "\n- file ".join(str(f) for f in missing_files)
        session.error(
            "Some required files are missing.\n"
            "Please make sure you run the related nox tasks first:\n"
            f"{missing}"
        )
    sha1 = str(
        session.run("git", "rev-parse", "HEAD", external=True, silent=True)
    ).strip()
    args: argparse.Namespace = parser.parse_args(args=session.posargs)
    project_report = create_report(commit=sha1)
    fmt = Format.from_string(args.format)

    print(format_report(project_report, fmt))
