"""
SentinelScan - Core Engine
Handles orchestration of modules, configuration, and reporting.
"""

import os
import json
import yaml
import logging
from sentinelscan.modules import port_scanner, subdomain, web_recon
from sentinelscan.modules import vuln_checks

# ============================================================
# Configuration
# ============================================================

CONFIG_FILE = "config.yaml"
DEFAULT_REPORT_DIR = "reports"

# ============================================================
# Helper Functions
# ============================================================

def ensure_directory(path: str):
    """Ensure a directory exists, create if missing."""
    if not os.path.exists(path):
        os.makedirs(path)


def load_config() -> dict:
    """Load configuration from config.yaml if available."""
    if os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE, "r", encoding="utf-8") as f:
            config = yaml.safe_load(f)
        logging.info("Config loaded from config.yaml")
        return config
    return {}


def save_report(filename: str, content: str):
    """Save report content to file."""
    ensure_directory(DEFAULT_REPORT_DIR)
    filepath = os.path.join(DEFAULT_REPORT_DIR, filename)
    with open(filepath, "w", encoding="utf-8") as f:
        f.write(content)
    print(f"[+] Report saved to {filepath}")
    logging.info(f"Report saved: {filepath}")


def generate_report(results, fmt="txt") -> str:
    """Generate report in specified format."""
    if fmt == "txt":
        report_content = ""
        for section, data in results:
            report_content += f"\n=== {section} ===\n"
            for item in data:
                report_content += f"{item}\n"
        return report_content

    elif fmt == "json":
        return json.dumps({sec: dat for sec, dat in results}, indent=4)

    elif fmt == "html":
        html_content = "<html><body><h1>SentinelScan Report</h1>"
        for section, data in results:
            html_content += f"<h2>{section}</h2><ul>"
            for item in data:
                html_content += f"<li>{item}</li>"
            html_content += "</ul>"
        html_content += "</body></html>"
        return html_content

    return ""


# ============================================================
# Module Orchestration
# ============================================================

def run_port_scan(target: str, ports: str) -> list:
    """Run port scanner module."""
    start_port, end_port = map(int, ports.split("-"))
    return port_scanner.scan_ports(target, start_port, end_port)


def run_subdomain_scan(target: str) -> list:
    """Run subdomain enumeration module."""
    return subdomain.find_subdomains(target)


def run_web_recon(target: str) -> list:
    """Run web reconnaissance module."""
    return web_recon.run_web_recon(target)


def run_vuln_checks(target: str) -> list:
    """Run vulnerability checks module."""
    return vuln_checks.run_checks(target)


# ============================================================
# Engine Class
# ============================================================

class SentinelEngine:
    """
    Core engine class for orchestrating scans.
    """

    def __init__(self, target: str, ports: str = "1-100", subdomains=False, web=False, vuln=False, output=None, fmt="txt"):
        self.target = target
        self.ports = ports
        self.subdomains = subdomains
        self.web = web
        self.vuln = vuln
        self.output = output
        self.format = fmt
        self.results = []
        self.config = load_config()

    def run(self):
        """Run selected modules."""
        print(f"[*] Starting SentinelScan on {self.target}...")

        # Port scan
        port_results = run_port_scan(self.target, self.ports)
        self.results.append(("Ports", port_results))

        # Subdomain scan
        if self.subdomains:
            sub_results = run_subdomain_scan(self.target)
            self.results.append(("Subdomains", sub_results))

        # Web recon
        if self.web:
            web_results = run_web_recon(self.target)
            self.results.append(("Web Recon", web_results))

        # Vulnerability checks
        if self.vuln:
            vuln_results = run_vuln_checks(self.target)
            self.results.append(("Vulnerabilities", vuln_results))

        # Reporting
        if self.output:
            report_content = generate_report(self.results, self.format)
            save_report(self.output, report_content)

        print("[+] SentinelScan complete.")
        return self.results


# ============================================================
# Testing Stub
# ============================================================

if __name__ == "__main__":
    # Example usage
    engine = SentinelEngine(
        target="example.com",
        ports="1-100",
        subdomains=True,
        web=True,
        vuln=True,
        output="example_report.txt",
        fmt="txt"
    )
    results = engine.run()
    for section, data in results:
        print(f"\n=== {section} ===")
        for item in data:
            print(item)
