import os
import json
import time
import re
import paramiko
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# --- Configuration Loader ---
def load_sftp_config(config_path):
    with open(config_path, 'r') as f:
        content = f.read()
        # Remove C-style comments (// ...) which Sublime's SFTP plugin uses
        content = re.sub(r'//.*', '', content)
        # Remove multiline comments /* ... */
        content = re.sub(r'/\*.*?\*/', '', content, flags=re.DOTALL)
        # Remove trailing commas
        content = re.sub(r',\s*([\]}])', r'\1', content)
        return json.loads(content)

CONFIG = load_sftp_config('sftp-config.json')

class SFTPHandler(FileSystemEventHandler):
    def __init__(self):
        self.host = CONFIG['host']
        self.port = int(CONFIG.get('port', 5069))
        self.user = CONFIG['user']
        self.password = CONFIG['password']
        self.remote_root = CONFIG['remote_path']
        self.ignore_regexes = [re.compile(r) for r in CONFIG.get('ignore_regexes', [])]
        
        self.transport = None
        self.sftp = None
        self.connect()

    def connect(self):
        print(f"[*] Connecting to {self.host}:{self.port}...")
        try:
            self.transport = paramiko.Transport((self.host, self.port))
            self.transport.connect(username=self.user, password=self.password)
            self.sftp = paramiko.SFTPClient.from_transport(self.transport)
            print("[+] Connected successfully.")
        except Exception as e:
            print(f"[-] Connection failed: {e}")

    def should_ignore(self, local_path):
        rel_path = os.path.relpath(local_path, ".").replace("\\", "/")
        for regex in self.ignore_regexes:
            if regex.search(rel_path):
                return True
        return False

    def on_modified(self, event):
        if event.is_directory:
            return
        
        local_path = event.src_path
        if self.should_ignore(local_path):
            return

        print(f"[*] Change detected: {local_path}")
        self.upload_file(local_path)

    def upload_file(self, local_path):
        rel_path = os.path.relpath(local_path, ".").replace("\\", "/")
        remote_path = os.path.join(self.remote_root, rel_path).replace("\\", "/")
        
        try:
            # Ensure remote directory exists
            remote_dir = os.path.dirname(remote_path)
            self.makedirs(remote_dir)
            
            print(f"[*] Uploading to {remote_path}...")
            self.sftp.put(local_path, remote_path)
            print("[+] Upload complete.")
        except Exception as e:
            print(f"[-] Upload failed: {e}")
            # Try to reconnect and retry once
            self.connect()
            try:
                self.sftp.put(local_path, remote_path)
                print("[+] Upload complete after reconnect.")
            except:
                print("[-] Retry failed.")

    def makedirs(self, remote_dir):
        dirs = remote_dir.split('/')
        current = ""
        for d in dirs:
            if not d: continue
            current += "/" + d
            try:
                self.sftp.stat(current)
            except IOError:
                self.sftp.mkdir(current)

if __name__ == "__main__":
    print("=== Antigravity SFTP Sync Starter ===")
    event_handler = SFTPHandler()
    observer = Observer()
    observer.schedule(event_handler, path='.', recursive=True)
    observer.start()
    print("[*] Watching for changes. Press Ctrl+C to stop.")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
