#!/usr/bin/env python3
"""
Module: quality_analyzer.py
Description: This module provides a code quality analyzer that checks for common
             issues such as PEP 8 violations, potential security vulnerabilities,
             and code complexity.

Author: Genesis System Worker
"""

import os
import subprocess
import logging
from typing import List, Dict, Tuple

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


class CodeQualityAnalyzer:
    """
    A class for analyzing code quality using various tools and checks.
    """

    def __init__(self, target_directory: str):
        """
        Initializes the CodeQualityAnalyzer with the target directory to analyze.

        Args:
            target_directory (str): The path to the directory containing the code to analyze.
        """
        self.target_directory = target_directory
        self.results: Dict[str, List[str]] = {}  # Store results per tool/check

    def run_flake8(self) -> None:
        """
        Runs Flake8 to check for PEP 8 violations and other style issues.
        """
        try:
            logging.info("Running Flake8...")
            result = subprocess.run(
                ["flake8", self.target_directory],
                capture_output=True,
                text=True,
                check=False,
            )

            if result.returncode == 0:
                logging.info("Flake8 completed successfully.")
            else:
                logging.warning(f"Flake8 exited with code: {result.returncode}")

            self.results["flake8"] = [line for line in result.stdout.splitlines()]

        except FileNotFoundError:
            logging.error("Flake8 is not installed. Please install it using: pip install flake8")
            self.results["flake8"] = ["Flake8 is not installed."]
        except Exception as e:
            logging.exception(f"An error occurred while running Flake8: {e}")
            self.results["flake8"] = [f"An error occurred: {e}"]


    def run_bandit(self) -> None:
        """
        Runs Bandit to check for potential security vulnerabilities.
        """
        try:
            logging.info("Running Bandit...")
            result = subprocess.run(
                ["bandit", "-r", self.target_directory],
                capture_output=True,
                text=True,
                check=False,
            )
            if result.returncode == 0:
                 logging.info("Bandit completed successfully.")
            else:
                 logging.warning(f"Bandit exited with code: {result.returncode}")

            self.results["bandit"] = [line for line in result.stdout.splitlines()]
        except FileNotFoundError:
            logging.error("Bandit is not installed. Please install it using: pip install bandit")
            self.results["bandit"] = ["Bandit is not installed."]
        except Exception as e:
            logging.exception(f"An error occurred while running Bandit: {e}")
            self.results["bandit"] = [f"An error occurred: {e}"]

    def analyze_code_complexity(self) -> None:
        """
        Analyzes code complexity by counting lines of code (LOC) and calculating
        the Cyclomatic Complexity (using a basic heuristic).
        """
        try:
            logging.info("Analyzing code complexity...")
            total_lines = 0
            complex_lines = 0  # Heuristic: count lines with control flow statements

            for root, _, files in os.walk(self.target_directory):
                for file in files:
                    if file.endswith(".py"):
                        filepath = os.path.join(root, file)
                        with open(filepath, "r", encoding="utf-8") as f:
                            for line in f:
                                line = line.strip()
                                total_lines += 1
                                if any(
                                    keyword in line
                                    for keyword in ["if", "for", "while", "try", "except", "def"]
                                ):
                                    complex_lines += 1

            complexity_ratio = (
                complex_lines / total_lines if total_lines > 0 else 0
            )  # Example heuristic metric

            self.results["complexity"] = [
                f"Total lines of code: {total_lines}",
                f"Lines with control flow: {complex_lines}",
                f"Complexity ratio (control flow / total LOC): {complexity_ratio:.2f}",
            ]

            logging.info("Code complexity analysis completed.")

        except Exception as e:
            logging.exception(f"An error occurred during complexity analysis: {e}")
            self.results["complexity"] = [f"An error occurred: {e}"]


    def run_analysis(self) -> Dict[str, List[str]]:
        """
        Runs all the code quality checks and returns the aggregated results.

        Returns:
            Dict[str, List[str]]: A dictionary containing the results of each check,
                                with the tool name as the key and a list of strings
                                representing the output as the value.
        """
        self.run_flake8()
        self.run_bandit()
        self.analyze_code_complexity()
        return self.results

    def print_results(self) -> None:
        """
        Prints the analysis results to the console.
        """
        for tool, findings in self.results.items():
            print(f"\n--- {tool.upper()} RESULTS ---")
            if findings:
                for finding in findings:
                    print(finding)
            else:
                print("No issues found.")


def main() -> None:
    """
    Main function to execute the code quality analysis.
    """
    target_directory = "/mnt/e/genesis-system/core"  # Replace with your target directory
    analyzer = CodeQualityAnalyzer(target_directory)
    results = analyzer.run_analysis()
    analyzer.print_results()


if __name__ == "__main__":
    main()