#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#
#   Author  :   renyuneyun
#   E-mail  :   renyuneyun@gmail.com
#   Date    :   2017-04-03 18:32:16
#   License :   GPLv2+
#
import importlib.util
import os
spec = importlib.util.spec_from_file_location("module.name", os.path.join(os.path.dirname(os.path.realpath(__file__)), "ps-lsof.py"))
ps_lsof = importlib.util.module_from_spec(spec)
spec.loader.exec_module(ps_lsof)
# TODO: dirty hack. Should be removed in the future.

import argparse
import sys

def processes_with_pacman_changes(dbpath='/var/cache/pacman-ps/files.db'):
    results = [] # [(pid, filename, package), ...]
    with open(dbpath) as db:
        file_to_pkg = {}
        for line in db:
            pkg, fname = [part.strip() for part in line.split(' ', 1)]
            file_to_pkg[fname] = pkg
    for pid, fname in ps_lsof.processes_with_deleted_files():
        if fname in file_to_pkg:
            results.append((pid, fname, file_to_pkg[fname]))
    return results

def pacman_ps():
    return [(fname, ps_lsof.process_name(pid), pkg) for (pid, fname, pkg) in processes_with_pacman_changes()]

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Show running processes that use old files changed by pacman.')
    parser.add_argument('-s', help='only show files and packages', action="store_true")
    parser.add_argument('-q', help='do not display title', action="store_true")
    args = parser.parse_args()
    def lx(x):
        return lambda lst: len(lst[x])
    def limit_len_left(s, max_len):
        if max_len == -1:
            return s
        return "{:<{}s}".format(s[:max_len], max_len)
    triples = pacman_ps()
    if len(triples) == 0:
        sys.exit()
    if not args.q:
        triples = [("FILENAME", "PROCESS", "PACKAGE")]+triples
    MAXLEN_FNAME = max(map(lx(0), triples))
    MAXLEN_PNAME = max(map(lx(1), triples))
    MAXLEN_PKG = max(map(lx(2), triples))
    for fname, pname, pkg in triples:
        if args.s:
            print("{}\t{}".format(limit_len_left(fname, MAXLEN_FNAME), limit_len_left(pkg, MAXLEN_PKG)))
        else:
            print("{}\t{}\t{}".format(limit_len_left(fname, MAXLEN_FNAME), limit_len_left(pname, MAXLEN_PNAME), limit_len_left(pkg, MAXLEN_PKG)))

