#!/usr/bin/env python3
"""
Show missing po entries for a directory
"""
import sys
from os.path import isfile, join, realpath, relpath, basename, dirname
from polib import pofile
import argparse
for attempt in range(2):
    try:
        from mkcmdlinegame import onlydirs, onlyfiles
        from mkcmdlinegame.po import \
            find_po_references, fetch_langs, _get_po_comment
        from mkcmdlinegame.colors import YELLOW, RYELLOW
    except ImportError:
        sys.path.append(
            join(dirname(dirname(realpath(__file__))), 'lib', 'python3')
        )
        continue
    break


def _po_check(d, langs, rec=False, po_source=False):
    po_refs = find_po_references(d)
    lines = []
    prtlist = []
    extra = []
    comments = []
    for lang in langs:
        # msgids_found = False
        po_orig = False
        po_fname = join(d, '%s.po' % lang)
        if isfile(po_fname):
            po_orig = pofile(po_fname)
            for msg_id in list(
                    set(map(lambda e: e.msgid, po_orig)) -
                    set(po_refs)
            ):
                entry = po_orig.find(msg_id)
                comment = _get_po_comment(entry)
                extra.append(
                    YELLOW % "[%s] %s" % (lang, msg_id) +
                    ('\n%s\n%s' % (comment, entry.msgstr) if comment else '')
                )
        else:
            lines += ['Oops ! Missing file %s' % relpath(po_fname)]
        for msg_id in po_refs:
            if not (po_orig and po_orig.find(msg_id)):
                prtlist.append('  missing %s' % msg_id)
            elif po_orig:
                entry_tgt = po_orig.find(msg_id)
                entry_src = po_source.find(msg_id) if po_source else False
                comment = _get_po_comment(entry_tgt)
                if comment:
                    comments.append(
                        YELLOW % "[%s] %s" % (lang, msg_id) +
                        '\n%s\n%s' % (comment, entry_tgt.msgstr)
                    )
                if not entry_tgt.msgstr:
                    if entry_src and entry_src.msgstr:
                        prtlist.append(
                            '  %s (to inject :: %s)' %
                            (
                                msg_id,
                                entry_src.msgstr.split('\n')[0][0:40] +
                                '...' if len(
                                    entry_src.msgstr) > 40 else '')
                        )
                    else:
                        prtlist.append('  %s (empty)' % msg_id)
        if prtlist:
            lines += ['%s' % relpath(po_fname)] + [
                YELLOW % "\n".join(prtlist)]
    if extra:
        extra.sort()
        print(RYELLOW % ' Extra po entries ' + ' in %s' % basename(d))
        for msg in extra:
            print(msg)

    if comments:
        extra.sort()
        print(RYELLOW % ' Comments on entries ' + ' in %s' % basename(d))
        for msg in comments:
            print(msg)

    if lines:
        print(RYELLOW % ' Missing msgids ' + ' in %s' % basename(d))
        for msg in lines:
            print(msg)

    if rec:
        for r in onlydirs(d):
            _po_check(r, langs, po_source=po_source)


def _global_check(d, langs, po_source=False):
    for lang in langs:
        occur = {}
        if po_source:
            for entry in po_source:
                occur[entry.msgid] = []

        occurx = {}
        for f in onlyfiles(d, ext='%s.po' % lang, rec=True):
            try:
                entries = pofile(f)
                for entry in entries:
                    i = entry.msgid
                    if i in occur:
                        occur[i].append(relpath(f))
                    elif i in occurx:
                        occurx[i].append(relpath(f))
                    else:
                        occurx[i] = [relpath(f)]
            except:
                continue

        msgids_missing = [i for i in occur.keys() if len(occur[i]) == 0]
        msgids_dbl = [i for i in occur.keys() if len(occur[i]) > 1]
        # msgids_new = [i for i in occurx.keys() if len(occurx[i]) == 1]
        msgids_new_dbl = [i for i in occurx.keys() if len(occurx[i]) > 1]
        msgids_missing.sort()
        msgids_new_dbl.sort()
        msgids_dbl.sort()

        if msgids_new_dbl or msgids_dbl:
            print('MSGIDS redefined :')
            for i in msgids_new_dbl:
                print('  %s IN %s' %
                      (" ".join(i.split()), " AND ".join(occurx[i])))
            for i in msgids_dbl:
                print('  %s IN %s' %
                      (" ".join(i.split()), " AND ".join(occur[i])))
            print("\n")

        if po_source:
            print('MSGIDS missing:')
            for i in msgids_missing:
                msgstr = po_source.find(i).msgstr
                print("  %s %s" % (
                    " ".join(i.split()), ':: ' +
                    (" ".join(msgstr.split()))[0:40] +
                    ('...' if len(msgstr) > 40 else '')
                ))


def main(d=None, g=None, po_source=None, rec=None, langs=None):
    d = realpath(d)
    langs = langs or fetch_langs(d)
    po = po_source and pofile(po_source) or False

    if g:
        _global_check(d, langs, po)
    else:
        _po_check(d, langs, po_source=po, rec=rec)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('d', metavar='dir')
    parser.add_argument('langs', metavar='lang[.po]', nargs='*')
    parser.add_argument('-rec', help="recursive", action='store_true')
    parser.add_argument('-g', help="global", action='store_true')
    args = parser.parse_args()

    for i, v in enumerate(args.langs):
        if v.endswith('.po'):
            args.po_source = v
            args.langs[i] = v[:-3]

    main(**vars(args))
