#!/usr/bin/env python3
import sys
from argparse import ArgumentParser
from json import loads
from pathlib import Path
from subprocess import PIPE, Popen
from sys import stderr
from typing import TypedDict

parser = ArgumentParser(prog="restic-search")
parser.add_argument("search", type=str, nargs="+")
parser.add_argument(
    "-n", "--last", type=int, help="Only search through the n latest snapshots"
)


class Snapshot(TypedDict):
    id: str


def restic_snapshots() -> list[Snapshot]:
    ps = Popen(["restic", "snapshots", "--json"], stdout=PIPE)
    stdout, _ = ps.communicate()
    if ps.returncode != 0:
        raise RuntimeError(
            f"Error while running restic snapshots: returncode {ps.returncode}"
        )
    j = loads(stdout.decode("utf-8"))
    return j


def restic_ls(snapshot_id: str) -> list[str]:
    ps = Popen(["restic", "ls", snapshot_id], stdout=PIPE)
    stdout, _ = ps.communicate()
    if ps.returncode != 0:
        raise RuntimeError(f"Error while running restic ls: returncode {ps.returncode}")
    return stdout.decode("utf-8").split("\n")


if __name__ == "__main__":
    args = parser.parse_args()
    stderr.write("Listing snapshots...\n")
    snapshots = restic_snapshots()
    if args.last:
        snapshots = snapshots[-args.last :]
    results = []
    for snapshot in snapshots:
        stderr.write(f"Listing files in snapshot {snapshot['id']}...\n")
        files = restic_ls(snapshot["id"])
        for file in files:
            path = Path(file)
            for search in args.search:
                if path.match(search):
                    results.append((search, file, snapshot["id"]))

    for result in results:
        print(f"{result[0]}\t{result[1]}\t{result[2]}")
