# !/usr/bin/env python3
import argparse
import requests
import os
import logging
import urllib3
import validators
from rich.console import Console
from rich import print
from rich.style import Style
from rich.text import Text
from datetime import datetime
from urllib.parse import urlparse
from concurrent.futures import ThreadPoolExecutor, as_completed

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
logger = logging.getLogger(__name__)
console = Console()

def validate_url(url):
    if not validators.url(url):
        console.print(f"[bold red]Invalid URL format:[/bold red] {url}")
        return False
    return True

def validate_proxy(proxy):
    parsed = urlparse(proxy)
    if not parsed.scheme in ['http', 'https']:
        console.print(f"[bold red]Invalid proxy format:[/bold red] {proxy}")
        return False
    return True

def send_to_burp(url, proxy):
    try:
        proxies = {
            'http': proxy,
            'https': proxy
        }

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br',
            'Connection': 'keep-alive'
        }

        response = requests.get(url, proxies=proxies, headers=headers, verify=False)  # Removed timeout
        console.print(f"[bold green]Sent request to Burp Suite:[/bold green] {url}")

        if response.status_code == 200:
            pass
        else:
            pass
    except requests.exceptions.Timeout:
        console.print(f"[bold red]Error:[/bold red] Request to {url} timed out.")
        logger.error(f"Timeout: {url}")
    except requests.exceptions.RequestException as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        logger.error(f"RequestException: {url} - {e}")

def handle_url_list(file_path, proxy):
    try:
        with open(file_path, 'r') as file:
            urls = [line.strip() for line in file if line.strip() and validate_url(line.strip())]
        
        with ThreadPoolExecutor(max_workers=10) as executor:  # --> You can adjust max_workers
            futures = [executor.submit(send_to_burp, url, proxy) for url in urls]

            for future in as_completed(futures):
                future.result()  

    except FileNotFoundError:
        console.print(f"[bold red]Error:[/bold red] File not found: {file_path}")
    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        logger.error(f"File Error: {file_path} - {e}")

def display_intro():
    username = os.getlogin()
    current_time = datetime.now().strftime("%A, %B %d, %Y - %I:%M:%S %p")
    console.print(f"\n[bold green]╭─────────────────────────── Security Analysis Tool ───────────────────────────╮[/bold green]")
    console.print(f"[bold green]│                                                                              │[/bold green]")
    console.print(f"[bold green]│        ███████╗ ██████╗ ██████╗  ██████╗                                     │[/bold green]")
    console.print(f"[bold green]│        ╚══███╔╝██╔═══██╗██╔══██╗██╔═══██╗                                    │[/bold green]")
    console.print(f"[bold green]│          ███╔╝ ██║   ██║██████╔╝██║   ██║                                    │[/bold green]")
    console.print(f"[bold green]│         ███╔╝  ██║   ██║██╔══██╗██║   ██║                                    │[/bold green]")
    console.print(f"[bold green]│        ███████╗╚██████╔╝██║  ██║╚██████╔╝                                    │[/bold green]")
    console.print(f"[bold green]│        ╚══════╝ ╚═════╝ ╚═╝  ╚═╝ ╚═════╝                                     │[/bold green]")
    console.print(f"[bold green]│                                                                              │[/bold green]")
    console.print(f"[bold green]│    Version: 1.0.2                                                            │[/bold green]")
    console.print(f"[bold green]│    Started at: {current_time}                     │[/bold green]")
    console.print(f"[bold green]│                                                                              │[/bold green]")
    console.print(f"[bold green]│                                                                              │[/bold green]")
    console.print(f"[bold green]╰─────────────────────────── By Zoro(whomaikiddie) ────────────────────────────╯[/bold green]")

def display_help():
    console.print("[bold cyan]Usage:[/bold cyan] python zoroflow.py [options]")
    console.print("\n[bold yellow]Options:[/bold yellow]")
    console.print("[bold yellow]  -h, --help      Show this help message[/bold yellow]")
    console.print("[bold yellow]  -u, --url       URL to send to Burp Suite[/bold yellow]")
    console.print("[bold yellow]  -l, --list      File containing list of URLs[/bold yellow]")
    console.print("[bold yellow]  -p, --proxy     Burp Suite proxy (default: http://127.0.0.1:7777)[/bold yellow]\n")


    console.print("\n[bold yellow]Setting up Burp Suite for Zoroflow:[/bold yellow]")
    console.print("""
Before using **Zoroflow**, you need to configure Burp Suite to listen on port 7777. Here’s how you can do that:

1. Open Burp Suite.
2. Go to the Proxy tab.
3. In the Proxy tab, click on Proxy Settings.
4. In the Proxy Listeners section, click on Add.
5. Set the listener interface to 127.0.0.1 and the port to 7777 (or any port you want to use).
6. Once configured, Burp Suite will listen on the specified port, and you can send traffic to it from Zoroflow.
7. You can now use Zoroflow to send URLs to Burp Suite for security analysis.
""")


def main():
    # --> CLI argument
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-h", "--help", action="store_true", help="Show help message")
    parser.add_argument("-u", "--url", type=str, help="URL to send to Burp Suite")
    parser.add_argument("-l", "--list", type=str, help="File containing list of URLs")
    parser.add_argument("-p", "--proxy", type=str, default="http://127.0.0.1:7777", help="Burp Suite proxy")

    args = parser.parse_args()

    if args.help:
        display_help()
        return

    display_intro()

    if not validate_proxy(args.proxy):
        return

    # --> Check if URL or list is provided
    if args.url:
        if validate_url(args.url):
            send_to_burp(args.url, args.proxy)
    elif args.list:
        if not os.path.exists(args.list):
            console.print(f"[bold red]Error:[/bold red] File not found: {args.list}")
            return
        handle_url_list(args.list, args.proxy)
    else:
        console.print("[bold red]Error:[/bold red] No URL or file provided. Use -h for help.")

if __name__ == "__main__":
    main()
