#!/usr/bin/env python3

from __future__ import print_function

import argparse
import os
import shutil
from pathlib import Path


def main():
    parser = argparse.ArgumentParser(description='Keep a bounded number of immutable platform releases.')
    parser.add_argument('root')
    parser.add_argument('limit', type=int)
    parser.add_argument('protected', nargs='*')
    args = parser.parse_args()

    root = Path(args.root).resolve()
    releases = (root / 'releases').resolve()
    if root == Path('/') or releases.parent != root or not releases.is_dir():
        raise SystemExit('unsafe or missing release root: {}'.format(releases))
    if args.limit < 2:
        raise SystemExit('release history limit must be at least 2')

    protected = set()
    for value in args.protected:
        path = Path(value).resolve()
        if path.parent != releases or not path.is_dir():
            raise SystemExit('protected release is outside the release root: {}'.format(path))
        protected.add(path)

    metadata_removed = 0
    for path in releases.iterdir():
        if path.is_file() and path.name.startswith('._'):
            path.unlink()
            metadata_removed += 1

    candidates = [path.resolve() for path in releases.iterdir() if path.is_dir() and not path.is_symlink()]
    candidates.sort(key=lambda path: path.stat().st_mtime, reverse=True)
    keep = set(protected)
    for path in candidates:
        if len(keep) >= args.limit:
            break
        keep.add(path)

    removed = 0
    for path in candidates:
        if path in keep:
            continue
        if path.parent != releases:
            raise SystemExit('refusing to remove a nested or escaped path: {}'.format(path))
        shutil.rmtree(str(path))
        removed += 1

    print('release_prune=ok before={} kept={} removed={} metadata_removed={}'.format(
        len(candidates), len(keep), removed, metadata_removed
    ))


if __name__ == '__main__':
    main()
