#!/usr/bin/env python3
import tomllib
from os import environ
from sys import argv
from typing import List, Dict
from pathlib import Path
from subprocess import Popen, PIPE


def get_alias_dir(dir_src: Path) -> str:
    return "/do-backup/" + str(dir_src.absolute()).replace("/", "__")[2:]


def get_folders_from_snapshot_folder(snapshot_folder: str) -> List[Path]:
    folder = Path(snapshot_folder)
    services: Dict[str, Path] = {}

    for subfolder in folder.glob("*-finish"):
        if not subfolder.is_dir():
            continue
        service = subfolder.name.rsplit('-', 3)[0]
        if service not in services:
            services[service] = subfolder
        elif sorted([subfolder.name, services[service].name])[-1] == subfolder.name:
            services[service] = subfolder

    return [(dir_snapshot, get_alias_dir(dir_snapshot.parent) + f"__{name}") for name, dir_snapshot in services.items()]


def main() -> None:
    try:
        FILE_CONFIG = Path(argv[1])
    except IndexError:
        FILE_CONFIG = Path('config.toml')

    with FILE_CONFIG.open('rb') as f:
        CONFIG = tomllib.load(f)
        REPO = CONFIG["REPO"]
        FILE_PASSWORD = CONFIG["FILE_PASSWORD"]
        FOLDERS = CONFIG["FOLDERS"]
        SNAPSHOT_FOLDERS = CONFIG["SNAPSHOT_FOLDERS"]
        EXCLUDED = CONFIG["EXCLUDED"]

    folders = [(Path(x), get_alias_dir(Path(x))) for x in FOLDERS]
    for snapshot_folder in SNAPSHOT_FOLDERS:
        folders.extend(get_folders_from_snapshot_folder(snapshot_folder))

    print('Backing up folders:')
    print('\n'.join(sorted([f'- {dir_src.absolute()}' for (dir_src, _) in folders])))

    env = {}
    env.update(environ)
    env['BORG_REPO'] = REPO
    env['BORG_PASSPHRASE'] = Path(FILE_PASSWORD).read_text().strip()

    command = ["bwrap", "--dev-bind", "/", "/"]
    for dir_src, alias in folders:
        command += ["--ro-bind", f"{dir_src.absolute()}", alias]
    command += ["--"]
    command += ['borg', 'create', '--verbose', '--list', '--filter', 'AME', '--stats', '--show-rc', '--compression', 'zstd,16']
    if EXCLUDED:
        for excluded in EXCLUDED:
            command += ['--exclude', excluded]
    command += ['::{now}'] + [alias for (_, alias) in folders]

    print('Executing command:')
    print('-', ' '.join(command))

    process = Popen(
        command,
        stdin=PIPE,
        text=True,
        env=env
    )
    process.communicate(input='')
    exit(process.returncode)


if __name__ == "__main__":
    main()
