#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import hashlib

EXCLUDED_FILES = {"done_by.script"}

def get_all_files(base_dir):
    """Recursively get all file paths in a directory"""
    file_map = {}
    for root, _, files in os.walk(base_dir):
        for file in files:
            if file in EXCLUDED_FILES:
                continue
            full_path = os.path.join(root, file)
            rel_path = os.path.relpath(full_path, base_dir)
            file_map[rel_path] = full_path
    return file_map


def sha1sum(filepath, block_size=65536):
    """Compute SHA-1 hash of a file (faster than byte-by-byte)"""
    h = hashlib.sha1()
    with open(filepath, 'rb') as f:
        for chunk in iter(lambda: f.read(block_size), b''):
            h.update(chunk)
    return h.hexdigest()


def remove_duplicates(old_dir, new_dir):
    print(f"[RUF] Indexing source version: {old_dir}")
    old_files = get_all_files(old_dir)
    print(f"[RUF] Indexing target version: {new_dir}")
    new_files = get_all_files(new_dir)

    print(f"[RUF] Comparing {len(new_files)} files")

    deleted = 0
    for rel_path, new_full_path in new_files.items():
        old_full_path = old_files.get(rel_path)
        if old_full_path and os.path.exists(old_full_path):
            try:
                if os.path.getsize(old_full_path) != os.path.getsize(new_full_path):
                    continue
                if sha1sum(old_full_path) == sha1sum(new_full_path):
                    os.remove(new_full_path)
                    print(f"[RUF] Removed duplicate: {new_full_path}")
                    deleted += 1
            except Exception as e:
                print(f"[ERR] Failed comparing {rel_path}: {e}")

    print(f"[RUF] Done. Deleted {deleted} duplicate files.")


def remove_empty_folders(path):
    """Recursively remove empty folders from a path"""
    for root, dirs, files in os.walk(path, topdown=False):
        for d in dirs:
            full_path = os.path.join(root, d)
            try:
                if not os.listdir(full_path):
                    os.rmdir(full_path)
                    print(f"[RUF] Deleted empty folder: {full_path}")
            except Exception as e:
                print(f"[ERR] Could not delete folder {full_path}: {e}")


def run(version_dir: str, old_version: str, current_version: str) -> None:
    os.chdir(version_dir)
    print(f"[RUF] Set Game_Location to {version_dir}")
    print(f"[RUF] Start comparing Version '{current_version}' to '{old_version}'")

    try:
        old_path = os.path.join(version_dir, old_version)
        new_path = os.path.join(version_dir, current_version)

        if not os.path.exists(old_path) or not os.path.exists(new_path):
            print(f"[ERR] One of the directories does not exist.")
            return

        remove_duplicates(old_path, new_path)
        remove_empty_folders(new_path)
    except Exception as e:
        print(f"[ERR] Failed during processing: {e}")

def run_against_latest(path, new_version):
    run(path, "latest", new_version)

if __name__ == "__main__":
    # Example usage
    #run_against_latest(path=r'S:/SaintCoinach/SaintCoinach.Cmd/bin/Release/Versions', new_version='2026.02.20.0000.0000')
    run_against_latest(path=r'/array/remotes/192.168.2.11_Github/SaintCoinach/SaintCoinach.Cmd/bin/Release/Versions', new_version='2026.03.17.0000.0000')
    #print(os.path.exists("/array/remotes/192.168.2.11_Github/SaintCoinach/SaintCoinach.Cmd/bin/Release/Versions"))