import hashlib
import os
import shutil
from datetime import datetime
from pathlib import Path


def gcstruct_backup(base_dir: str) -> None:
    print("Sicherung fuer GCStruct")
    for f in Path(base_dir).rglob("Kontenrahmen.csv"):
        if f.parent.name == "Kontenrahmen":
            print("* " + str(f))
            copy_file_with_timestamp(str(f), str(f.parent / "Backup"))


def copy_file_with_timestamp(file_path: str, backup_folder: str) -> None:
    """
    Copies a file to a backup folder with a timestamp in the filename
    only if the file has changed since last run.
    """
    if not Path(backup_folder).exists():
        os.makedirs(backup_folder, exist_ok=True)

    file_mod_timestamp = datetime.fromtimestamp(Path(file_path).stat().st_mtime).strftime("%Y%m%d_%H%M%S")
    file_extension = Path(file_path).suffix
    file_basename = Path(file_path).stem
    backup_filename = f"{file_basename}__{file_mod_timestamp}{file_extension}"

    if Path(backup_folder + "\\" + backup_filename).exists():
        # backup folder is already up-to-date
        return

    latest_file = get_file_with_latest_timestamp(backup_folder, file_basename + "__")
    if latest_file != "" and hash(file_path) == hash(latest_file):
        # different timestamp, but same content. Keep old timestamp and backup file.
        return

    shutil.copy2(file_path, backup_folder + "\\" + backup_filename)
    return


def get_file_with_latest_timestamp(folder_path: str, filename_pattern: str) -> str:
    """
    Gets the latest timestamp from files in a folder with a matching filename.
    """
    files = [str(f) for f in Path(folder_path).iterdir() if f.name.startswith(filename_pattern)]
    if len(files) == 0:
        return ""
    files.sort()
    return files[-1]


def hash(filename: str) -> str:
    with open(filename, "rb") as frh:
        return hashlib.sha256(frh.read()).hexdigest()


def main() -> None:
    gcstruct_backup("C:\\GlobalCube_Entwicklung")


def copy_deployment(server_folder: str, backup_folder: str):
    filename = "GC_BACKUP_CONTENT_STORE_DAILY.zip"
    source_file = Path(server_folder + "\\deployment\\" + filename)
    if not source_file.exists():
        print(f"!! Datei {filename} existiert nicht !!")
        return
    file_ts = source_file.stat().st_mtime
    print(filename + " - " + datetime.fromtimestamp(file_ts).strftime("%d.%m.%Y %H:%M:%S"))

    if file_ts < datetime.now().timestamp() - 3 * 24 * 60 * 60:
        print(f"!! Datei {filename} ist aelter als 3 Tage !!")
        return

    if not Path(backup_folder).exists():
        os.makedirs(backup_folder, exist_ok=True)

    dest_file = Path(f"{backup_folder}\\{filename}")
    if dest_file.exists() and file_ts == dest_file.stat().st_mtime:
        print(f"Datei {filename} ist bereits up-to-date.")
        return
    shutil.copy2(source_file, dest_file)


if __name__ == "__main__":
    main()