#!/usr/bin/env python3
"""
SCH-033 Pass 3: Fix broken FCPATH patterns in exec() calls.

Issues to fix:
1. exec("...text ' . FCPATH . 'rest...")  -> exec("...text " . FCPATH . "rest...")
   (single-quote FCPATH concat inside double-quoted string)

2. exec("...text FCPATH . "rest...")  -> exec("...text " . FCPATH . "rest...")
   (bare FCPATH without proper string break)

3. exec("... FCPATH . "rest...")  -> exec("... " . FCPATH . "rest...")
   (FCPATH at boundary without closing first string)
"""
import os
import re
import shutil

BASE = '/var/www/html/dev_scheduler/SCHEDULER'
ENH_DIR = '/var/www/html/dev_scheduler/ENHANCEMENTS/SCH-033_dev_scheduler_cleanup'
MOD_DIR = os.path.join(ENH_DIR, 'modified')

stats = {'files_fixed': 0, 'fixes': 0}

def rel(path):
    return os.path.relpath(path, BASE)

def save_modified(filepath):
    relpath = rel(filepath)
    dest = os.path.join(MOD_DIR, relpath)
    os.makedirs(os.path.dirname(dest), exist_ok=True)
    shutil.copy2(filepath, dest)


def fix_file(filepath):
    with open(filepath, 'r', errors='replace') as f:
        content = f.read()

    original = content
    fixes = 0

    # Fix 1: ' . FCPATH . ' inside what should be double-quoted contexts
    # exec("mv -f $path ' . FCPATH . 'pdftemp/$name")
    # Should be: exec("mv -f $path " . FCPATH . "pdftemp/$name")
    old = "' . FCPATH . '"
    # Only replace when it appears inside a double-quoted string context
    # We detect this by looking for lines that start with exec(" or similar
    lines = content.split('\n')
    new_lines = []
    for line in lines:
        if old in line:
            # Check if this line has a double-quoted string context
            # (contains exec(" or shell_exec(" or similar with double quotes)
            stripped = line.lstrip()
            if (stripped.startswith('exec("') or
                stripped.startswith('shell_exec("') or
                stripped.startswith('//exec("') or
                'exec("' in stripped or
                'shell_exec("' in stripped or
                'exec("' in line):
                # Replace single-quote FCPATH with double-quote FCPATH
                line = line.replace(old, '" . FCPATH . "')
                fixes += 1
            elif ('exec(\'') in stripped or ('shell_exec(\'') in stripped:
                # Single-quoted exec - the ' . FCPATH . ' is correct PHP concat
                pass
            elif ('fopen(' in stripped or 'file_get_contents(' in stripped or
                  'attach(' in stripped or 'unlink(' in stripped or
                  'copy(' in stripped):
                # These are fine - they use FCPATH . "..." pattern
                pass
        new_lines.append(line)
    content = '\n'.join(new_lines)

    # Fix 2: Bare FCPATH without string concatenation operators
    # Pattern: ...text FCPATH . "rest..."   (missing " . before FCPATH)
    # Should be: ...text " . FCPATH . "rest..."
    # This happens at positions inside exec() strings
    # Regex: look for content where FCPATH appears without " . before it and after a letter/space
    content = re.sub(
        r'([a-zA-Z0-9_/\.\s])FCPATH \. "',
        lambda m: m.group(1) + '" . FCPATH . "' if m.group(1) not in ('"', "'", '.', '(') else m.group(0),
        content
    )

    # Fix 3: FCPATH . "..." where the preceding string isn't closed
    # Pattern in exec: exec("...wkhtmltopdf... FCPATH . "pdftemp/...
    # The " before FCPATH is actually part of the outer string - wrong.
    # After Fix 2, these should mostly be fixed.

    # Fix 4: Handle edge case: space + FCPATH not preceded by proper operator
    # Look for: " FCPATH . " where the first " is mid-string
    # This was already handled by the regex above.

    # Count remaining issues for reporting
    if content != original:
        # Count actual line-level fixes
        orig_lines = original.split('\n')
        new_lines = content.split('\n')
        fixes = sum(1 for a, b in zip(orig_lines, new_lines) if a != b)

        with open(filepath, 'w') as f:
            f.write(content)
        save_modified(filepath)
        stats['files_fixed'] += 1
        stats['fixes'] += fixes
        print(f"  Fixed: {rel(filepath)} ({fixes} lines)")

    return fixes


def main():
    print("=" * 70)
    print("PASS 3: Fix broken FCPATH patterns in exec() calls")
    print("=" * 70)

    # Find all PHP files that have FCPATH
    for root, dirs, files in os.walk(BASE):
        dirs[:] = [d for d in dirs if d not in {'_svn', '.svn'}]
        for f in sorted(files):
            if not f.endswith('.php'):
                continue
            filepath = os.path.join(root, f)
            try:
                with open(filepath, 'r', errors='replace') as fh:
                    text = fh.read()
                    if "' . FCPATH . '" in text or re.search(r'[a-zA-Z0-9_/\s]FCPATH \. "', text):
                        fix_file(filepath)
            except:
                pass

    print(f"\n  Files fixed: {stats['files_fixed']}")
    print(f"  Lines fixed: {stats['fixes']}")


if __name__ == '__main__':
    main()
