#!/usr/bin/env python3

"""
Module: coverage_report.py
Description: This module generates coverage reports for the Genesis system tests.
It uses the coverage.py library to collect coverage data and generate HTML reports.
"""

import argparse
import logging
import os
import sys
from typing import Optional

import coverage

# Configure logging
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)

class CoverageReporter:
    """
    A class to manage and generate coverage reports.
    """

    def __init__(self, source_paths: list[str] = None, omit_paths: list[str] = None):
        """
        Initializes the CoverageReporter.

        Args:
            source_paths (list[str], optional): List of source paths to include in coverage analysis. Defaults to None.
            omit_paths (list[str], optional): List of paths to omit from coverage analysis. Defaults to None.
        """
        self.cov = coverage.Coverage(source=source_paths, omit=omit_paths)
        self.source_paths = source_paths
        self.omit_paths = omit_paths

    def start(self) -> None:
        """
        Starts the coverage measurement.
        """
        try:
            self.cov.start()
            logging.info("Coverage measurement started.")
        except Exception as e:
            logging.error(f"Failed to start coverage measurement: {e}")
            raise

    def stop(self) -> None:
        """
        Stops the coverage measurement.
        """
        try:
            self.cov.stop()
            logging.info("Coverage measurement stopped.")
        except Exception as e:
            logging.error(f"Failed to stop coverage measurement: {e}")
            raise

    def save(self) -> None:
        """
        Saves the coverage data to a .coverage file.
        """
        try:
            self.cov.save()
            logging.info("Coverage data saved to .coverage file.")
        except Exception as e:
            logging.error(f"Failed to save coverage data: {e}")
            raise

    def generate_report(self, report_type: str = "html", output_dir: str = "coverage_html") -> None:
        """
        Generates a coverage report.

        Args:
            report_type (str, optional): The type of report to generate (e.g., "html", "xml", "term"). Defaults to "html".
            output_dir (str, optional): The directory to save the report to. Defaults to "coverage_html".
        """
        try:
            if report_type == "html":
                self.cov.html_report(directory=output_dir)
                logging.info(f"HTML coverage report generated in {output_dir}.")
            elif report_type == "xml":
                self.cov.xml_report(outfile=os.path.join(output_dir, "coverage.xml"))
                logging.info(f"XML coverage report generated in {output_dir}.")
            elif report_type == "term":
                self.cov.report(show_missing=True)
                logging.info("Terminal coverage report generated.")
            else:
                raise ValueError(f"Unsupported report type: {report_type}")

        except Exception as e:
            logging.error(f"Failed to generate {report_type} coverage report: {e}")
            raise

def main(args: argparse.Namespace) -> None:
    """
    Main function to generate coverage reports.

    Args:
        args (argparse.Namespace): Command-line arguments.
    """
    try:
        source_paths = args.source if args.source else None
        omit_paths = args.omit if args.omit else None

        reporter = CoverageReporter(source_paths=source_paths, omit_paths=omit_paths)
        reporter.start()

        # Execute the tests (replace this with your test execution logic)
        # Example:
        # import pytest
        # pytest.main(["-v", "tests/"])

        # For now, simulate running a dummy script to generate coverage data.
        # Replace 'dummy_module.py' with the actual module you want to test.
        try:
            import dummy_module  # type: ignore # Simulate importing a module. It won't exist.
        except ImportError:
            logging.warning("dummy_module.py not found.  Coverage report may be incomplete.")
            #Create an empty dummy_module so coverage tools don't throw errors
            open("dummy_module.py", 'a').close()
            import dummy_module #type: ignore

        reporter.stop()
        reporter.save()
        reporter.generate_report(report_type=args.report_type, output_dir=args.output_dir)

    except Exception as e:
        logging.error(f"An error occurred during coverage report generation: {e}")
        sys.exit(1)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Generate coverage reports for Genesis system tests.")
    parser.add_argument(
        "--report_type",
        type=str,
        default="html",
        choices=["html", "xml", "term"],
        help="Type of coverage report to generate (html, xml, term).",
    )
    parser.add_argument(
        "--output_dir",
        type=str,
        default="coverage_html",
        help="Directory to save the coverage report to.",
    )
    parser.add_argument(
        "--source",
        type=str,
        nargs='+',
        help="Source paths to include in coverage analysis.",
    )
    parser.add_argument(
        "--omit",
        type=str,
        nargs='+',
        help="Paths to omit from coverage analysis.",
    )
    args = parser.parse_args()
    main(args)