import os
import ast
import re
import json

def inspect_python_ast_entrypoint(file_path):
    """
    Parses a Python file using Python's native AST module.
    Detects Flask/FastAPI/Django WSGI app instance variable or factory function.
    Returns: 'app', 'application', 'create_app()', etc.
    """
    m_app = None
    m_fac = None
    m_wsgi = None

    if not os.path.exists(file_path):
        return 'app'

    try:
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            code = f.read()

        try:
            tree = ast.parse(code)
            for node in ast.walk(tree):
                if isinstance(node, ast.Assign):
                    for target in node.targets:
                        if isinstance(target, ast.Name):
                            var_name = target.id
                            if isinstance(node.value, ast.Call):
                                func_name = ''
                                if isinstance(node.value.func, ast.Name):
                                    func_name = node.value.func.id
                                elif isinstance(node.value.func, ast.Attribute):
                                    func_name = node.value.func.attr
                                
                                if func_name in ('Flask', 'FastAPI', 'Django', 'WSGIHandler'):
                                    m_app = var_name
                                    break
                            elif var_name in ('app', 'application', 'api'):
                                m_wsgi = var_name

                elif isinstance(node, ast.FunctionDef):
                    if node.name in ('create_app', 'make_app', 'build_app'):
                        m_fac = f"{node.name}()"

        except SyntaxError:
            pass

        if m_app is not None:
            return m_app
        if m_fac is not None:
            return m_fac
        if m_wsgi is not None:
            return m_wsgi

        match_regex = re.search(r'^\s*([a-zA-Z0-9_]+)\s*=\s*(?:Flask|FastAPI)\b', code, re.MULTILINE)
        if match_regex:
            return match_regex.group(1)

        match_fac = re.search(r'^\s*def\s+(create_app|make_app)\b', code, re.MULTILINE)
        if match_fac:
            return f"{match_fac.group(1)}()"

    except Exception:
        pass

    return 'app'

def run_remote_project_inspection(srv, target_staging_path):
    """
    Runs a deep inspection script on the VPS staging directory to discover:
    - Root real path (handling nested folders like server/ or src/ or root)
    - Framework (Flask, FastAPI, Node.js, Static)
    - Entrypoint script (app.py, main.py, run.py, server.py, index.js, etc.)
    - WSGI object name (app, application, create_app)
    - Requirements / Package dependencies
    Uses the __DEPLOYHUB_JSON__ marker to guarantee clean JSON extraction.
    """
    remote_inspector_script = f"""python3 - << 'EOF'
import os, sys, re, json, ast

staging = "{target_staging_path}"

# 1. Find root directory (if single nested folder)
subdirs = [os.path.join(staging, d) for d in os.listdir(staging) if os.path.isdir(os.path.join(staging, d)) and not d.startswith('.')]
files = [f for f in os.listdir(staging) if os.path.isfile(os.path.join(staging, f)) and not f.startswith('.')]

real_root = staging
rel_root = "."
if len(files) == 0 and len(subdirs) == 1:
    real_root = subdirs[0]
    rel_root = os.path.basename(real_root)

# 2. Search for entrypoint script
candidates = ['app.py', 'main.py', 'run.py', 'server.py', 'wsgi.py', 'index.js', 'server.js', 'app.js']
entry_script = None

for c in candidates:
    if os.path.exists(os.path.join(real_root, c)):
        entry_script = c
        break

if not entry_script:
    for root, dirs, filenames in os.walk(real_root):
        rel_dir = os.path.relpath(root, real_root)
        if rel_dir.count(os.sep) > 1 or '.venv' in rel_dir or 'venv' in rel_dir or 'node_modules' in rel_dir:
            continue
        for fname in filenames:
            if fname in candidates:
                entry_script = os.path.join(rel_dir, fname) if rel_dir != '.' else fname
                break
        if entry_script:
            break

# 3. Inspect WSGI Object Variable via AST
wsgi_object = 'app'
framework = 'Python Flask'

if entry_script and entry_script.endswith('.py'):
    ep_full = os.path.join(real_root, entry_script)
    try:
        with open(ep_full, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()

        if 'FastAPI' in content:
            framework = 'Python FastAPI'
        elif 'Django' in content:
            framework = 'Python Django'
        
        m_app = None
        m_fac = None
        
        try:
            tree = ast.parse(content)
            for node in ast.walk(tree):
                if isinstance(node, ast.Assign):
                    for target in node.targets:
                        if isinstance(target, ast.Name):
                            if isinstance(node.value, ast.Call):
                                func_n = getattr(node.value.func, 'id', getattr(node.value.func, 'attr', ''))
                                if func_n in ('Flask', 'FastAPI', 'Django'):
                                    m_app = target.id
                elif isinstance(node, ast.FunctionDef):
                    if node.name in ('create_app', 'make_app'):
                        m_fac = f"{{node.name}}()"
        except SyntaxError:
            pass

        if m_app is not None:
            wsgi_object = m_app
        elif m_fac is not None:
            wsgi_object = m_fac
        else:
            m_reg = re.search(r'^\s*([a-zA-Z0-9_]+)\s*=\s*(?:Flask|FastAPI)\b', content, re.MULTILINE)
            if m_reg:
                wsgi_object = m_reg.group(1)

    except Exception:
        pass

elif entry_script and entry_script.endswith('.js'):
    framework = 'Node.js'

has_req = os.path.exists(os.path.join(real_root, 'requirements.txt'))
has_pkg = os.path.exists(os.path.join(real_root, 'package.json'))
file_count = sum(len(f) for _, _, f in os.walk(real_root))

result_data = {{
    'real_root': real_root,
    'rel_root': rel_root,
    'entry_script': entry_script,
    'wsgi_object': wsgi_object,
    'framework': framework,
    'has_requirements': has_req,
    'has_package_json': has_pkg,
    'file_count': file_count
}}

print("__DEPLOYHUB_JSON__" + json.dumps(result_data))
EOF
"""
    from modules.ssh_manager import execute_command
    exit_code, out, err = execute_command(srv, remote_inspector_script)
    if exit_code != 0:
        raise Exception(f"Erro na inspeção do projeto no VPS: {err}")

    # Extract JSON line using __DEPLOYHUB_JSON__ marker
    marker = "__DEPLOYHUB_JSON__"
    json_line = None
    for line in out.splitlines():
        if marker in line:
            json_line = line.split(marker, 1)[1].strip()
            break

    if not json_line:
        raise Exception(f"Inspector remoto não retornou JSON com marcador __DEPLOYHUB_JSON__. Resposta STDOUT:\n{out[:300]}")

    try:
        return json.loads(json_line)
    except json.JSONDecodeError as e:
        raise Exception(f"Falha ao interpretar JSON do inspector: {e}. Resposta: {json_line[:200]}")
