import sys
import time
from . import ui
from .config import BANNER
from .ui import C
from .session import load_session, clear_session
from .context import CrackContext
from .gpu import detect_gpu
from .detect import detect_input,extract_hash_from_file
from .deps import run_dependencies
from .strategy import crack_raw_hash,crack_file_hash


def main():
    print(BANNER)
    patience_arg = None
    resume_mode = False

    for arg in sys.argv[1:]:
        if arg == "--resume":
            resume_mode = True
        elif arg.startswith("--patience="):
            patience_arg = arg.split("=", 1)[1].lower()

    if patience_arg and patience_arg not in ("quick", "normal", "patient"):
        ui.err(f"Invalid patience level '{patience_arg}'. Use quick/normal/patient.")
        sys.exit(1)

    if resume_mode:
        session = load_session()
        if not session:
            ui.err("No valid session found to resume")
            sys.exit(1)
        ui.info(f"Resuming session from {time.ctime(session['timestamp'])}")
    else:
        target = None
        for arg in sys.argv[1:]:
            if not arg.startswith('-'):
                target = arg
                break
        if target is None:
            print("Usage:")
            print("  quinto <hash_string>")
            print("  quinto <protected_file>")
            print("  quinto --resume")
            print("  quinto --patience=quick|normal|patient <hash>")
            print()
            print("Patience levels:")
            print("  quick   — rockyou only (fast, low coverage)")
            print("  normal  — rockyou + crackstation")
            print("  patient — everything including all wordlists with all rules")
            sys.exit(1)

    ctx = CrackContext(
        patience=patience_arg or "normal",
        gpu_flags=detect_gpu(),
        available_wl=run_dependencies(),
    )
    ui.info(f"Patience level: {ctx.patience}")
    ui.info(f"GPU flags: {' '.join(ctx.gpu_flags)}")

    if resume_mode:
        with open(session['hash_file'], 'r') as f:
            hash_str = f.read().strip()
        result = crack_raw_hash(hash_str, ctx, resume_session=session)
    else:
        detected = detect_input(target)
        result = None

        if detected[0] == 'file':
            _, filepath, ext, tool = detected
            ui.info(f"Protected file ({ext}) — extracting hash with {tool}")
            john_hash_file = extract_hash_from_file(filepath, tool)
            result = crack_file_hash(john_hash_file, ctx.available_wl)
        else:
            _, hash_str = detected
            ui.info(f"Raw hash: {C.BOLD}{hash_str}{C.RESET}")
            result = crack_raw_hash(hash_str, ctx)

    # Print the cracked or print did not find
    print(f"\n{C.BOLD}{C.CYAN}{'═' * 50}{C.RESET}")
    if result:
        print(f"  {C.GREEN}{C.BOLD}CRACKED!{C.RESET}  Plaintext: {C.GREEN}{C.BOLD}{result}{C.RESET}")
        clear_session()
    else:
        print(f"  {C.RED}{C.BOLD}NOT CRACKED{C.RESET} with available wordlists + rules.")
        print(f"\n  Resume later:  quinto --resume")
        print(f"\n  Things to try next:")
        print(f"    - Larger wordlists (hashes.org dumps)")
        print(f"    - More rule files")
        print(f"    - Manual mask: hashcat -a 3 -m <mode> hash ?a?a?a?a?a?a?a?a")
        print(f"    - Online: https://crackstation.net  |  https://hashes.com/en/decrypt/hash")
    print(f"{C.BOLD}{C.CYAN}{'═' * 50}{C.RESET}\n")

