#!/usr/bin/python3
'''
Information Collector for DUPR Collection
Copyright (C) 2019 M. Zhou <lumin@debian.org>
'''
import sys, os, re, json, argparse
from typing import *

green = lambda x: f'\x1b[32m{x}\x1b[m'
Yellow = lambda x: f'\x1b[1;33m{x}\x1b[m'
Cyan = lambda x: f'\x1b[1;36m{x}\x1b[m'
Red = lambda x: f'\x1b[1;31m{x}\x1b[m'


_META_FIELDS_ = ('src', 'description', 'version', 'license', 'section',
        'homepage', 'build_depends')
_META_COMPLAIN_ = ('src', 'description')


def collect(path: str) -> List[Dict]:
    '''
    Collect information from the specified Collection
    '''
    Collection = []  # A List of Dictionaries
    for root, dirs, files in os.walk(path):
        for name in files:
            if name.endswith('.rcp'):
                path = os.path.join(root, name)
                lines = open(path, 'r').readlines()
                d = {}
                for field in _META_FIELDS_:
                    regex = re.compile(f"^{field}=[\'\"](.*?)[\'\"]")
                    match = [x for x in lines if regex.match(x)]
                    if not match and field in _META_COMPLAIN_:
                        print(f'{path} missed the "{field}" variable !')
                    elif not match:
                        continue
                    value = regex.match(match[0]).group(1)  # XXX: maybe this is fine.
                    if len(value)>0: d[field] = value
                if ag.verbose: print(path, '... OK')
                d['.rcp'] = path
                Collection.append(d)
    return Collection


def prettyPrint(col: List[Dict]) -> None:
    '''
    Maybe mimicking the "emerge --search" style
    '''
    for item in col:
        print(f'\x1b[1;32m*  \x1b[1;37m{item[".rcp"]}\x1b[m')
        for k in sorted(item.keys()):
            color = green
            if k not in _META_FIELDS_: continue
            if k == 'build_depends':
                color = Red
            print(color(f'{k}:'.rjust(20)), f'{item[k]}')
        print()
    print('Found', Yellow(f'{len(col)}'),
          f'(matching) packages in "{ag.collection}"')


if __name__ == '__main__':

    ag = argparse.ArgumentParser()
    ag.add_argument('-o', '--output', type=str, default=None, help='save json')
    ag.add_argument('-v', '--verbose', action='store_true')
    ag.add_argument(
        '-s', '--search', type=str, default=None, help='python regex')
    ag.add_argument(
        'collection', nargs='?', default='.', help='scan witch dir?')
    ag = ag.parse_args()

    Collection = collect(ag.collection)

    if ag.search is not None:
        filtered = []
        for item in Collection:
            rcp, src, desc = item['.rcp'], item['src'], item[
                'description']
            if any([
                    re.match(ag.search, rcp),
                    re.match(ag.search, rcp.lower()),
                    (ag.search in rcp),
                    (ag.search in rcp.lower()),
                    re.match(ag.search, src),
                    re.match(ag.search, src.lower()),
                    (ag.search in src),
                    (ag.search in src.lower()),
                    re.match(ag.search, desc),
                    re.match(ag.search, desc.lower()),
                    (ag.search in desc),
                    (ag.search in desc.lower()),
            ]):
                filtered.append(item)
        prettyPrint(filtered)
    elif ag.output is not None:
        with open(ag.output, 'w') as f:
            f.write(json.dumps(Collection, indent=4))
    else:
        prettyPrint(Collection)
