import ftplib
import os
import pathlib

HOST = 'so.deployin.site'
USER = 'itsk@so.deployin.site'
PASS = 'ITSk@2026'
ROOT = pathlib.Path(r'C:\laragon\SIMRO-SIMRS KOTA MALANG\simrs-rsud-malang')
EXCLUDE_DIRS = {'.git', 'node_modules', 'docker', '__pycache__'}
EXCLUDE_FILES = {'.DS_Store'}


def normalize_remote(path: pathlib.Path) -> str:
    return path.as_posix().lstrip('/')


def ensure_remote_dirs(ftp: ftplib.FTP, remote_dir: str):
    if not remote_dir:
        return
    parts = remote_dir.split('/')
    current = ''
    for part in parts:
        current = f"{current}/{part}" if current else part
        try:
            ftp.mkd(current)
            print('Created remote dir:', current)
        except ftplib.error_perm as e:
            msg = str(e).lower()
            if 'already exists' in msg or 'file exists' in msg or '550' in msg:
                continue
            raise


def should_skip(path: pathlib.Path) -> bool:
    if path.name in EXCLUDE_FILES:
        return True
    for part in path.parts:
        if part in EXCLUDE_DIRS:
            return True
    return False


def gather_files(root: pathlib.Path):
    all_files = []
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(root):
        rel_dir = pathlib.Path(dirpath).relative_to(root)
        if should_skip(rel_dir):
            dirnames[:] = []
            continue
        dirnames[:] = [d for d in dirnames if not should_skip(rel_dir / d)]
        for filename in filenames:
            local_path = pathlib.Path(dirpath) / filename
            if should_skip(local_path.relative_to(root)):
                continue
            rel_file = local_path.relative_to(root)
            all_files.append(rel_file)
            total_size += local_path.stat().st_size
    return all_files, total_size


def upload_all():
    files, total_size = gather_files(ROOT)
    print(f'Found {len(files)} files to upload, total {total_size} bytes')

    ftp = ftplib.FTP(HOST, timeout=60)
    ftp.login(USER, PASS)
    print('FTP login successful')
    ftp.cwd('/')

    uploaded = 0
    for rel_file in files:
        local_path = ROOT / rel_file
        remote_dir = normalize_remote(rel_file.parent)
        ensure_remote_dirs(ftp, remote_dir)
        remote_path = f"{remote_dir}/{rel_file.name}" if remote_dir else rel_file.name
        with open(local_path, 'rb') as f:
            ftp.storbinary(f'STOR {remote_path}', f)
        uploaded += 1
        if uploaded % 100 == 0:
            print(f'Uploaded {uploaded}/{len(files)}: {remote_path}')

    print(f'Upload complete: {uploaded} files')
    ftp.quit()


if __name__ == '__main__':
    upload_all()
