#!/usr/bin/env python
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

# LibreOffice UI Strings Hunter

import argparse
import os
import subprocess
from subprocess import CalledProcessError
import re

class hunter:

    def __init__(self, string, file_selectors):
        self.prey = string
        self.fsel = file_selectors
        self.scents =  None

    def hunt(self):
        try:
            preypat = ''.join(set(self.prey + '_~'))
            # add +1 for potential hotkey sign
            pattern_counter = ('{' + str(len(self.prey)) + ','
                                   + str(len(self.prey) + 1) + '}')
            fullpat = '[">][' + preypat + ']' + pattern_counter + '["<]'
            self.scents = subprocess.check_output(
                            ['git', 'grep', '-EnI', fullpat.encode('ascii'), '--'] + 
                            self.fsel.split(None))
            
        except subprocess.CalledProcessError as e:
            if e.returncode == 1:  # git grep found nothing
                return False
            else:
                raise(e)
        except:
            raise
        return True

    def __get_lair(self, filename , linenum):
        if os.path.splitext(filename)[1] == '.ui':
            return filename.split('uiconfig/')[1]
        else:
            # for .?rc files, search the RESID
            # get the last word before the previous {
            with open(filename) as fcontent:
                head = [fcontent.next() for x in xrange(int(linenum))]
            lines = reversed(head)
            if lines:
                curly = False
                i = 0
                for line in iter(lines):
                    if curly:
                        return line.strip().split(' ')[-1]
                    if '{' in line:
                        curly = True
        return None

    def __smoke_out(self, key):
        # we'll filter on filename to exclude lairs 
        re_fsel = '(.*(' + self.fsel.replace('*','\\').replace(' ','[:-]|') + '[:-]).*)'
        scramble = "\n== Searching %s\n" % (key)
        
        # avoid a while with http://code.activestate.com/recipes/66061/#c1
        scramble += '\n'.join([line for line in subprocess.check_output(
                ['git', 'grep', '-EnI2', key.encode('ascii')]).splitlines()
                 if re.search(re_fsel, line) is None])
        return scramble

    
    def show_trophies(self):
        trophies = ""    
        line_matches = self.scents.splitlines()
        for match in line_matches:
            # result of git grep has this pattern
            [fname, line, text] = match.split(':', 2)
            ext = os.path.splitext(fname)[1]
            if ext == '.ui':
                text_splitter = '><'
                hotkey='_'
            else:
                text_splitter = '""'
                hotkey = '~'

            scent_match = (text.split(text_splitter[0])[1] 
                            .split(text_splitter[1])[0] 
                            .replace(hotkey,""))

            if self.prey == scent_match:
                lair = self.__get_lair(fname, line)
                if lair is not None:
                    print "Found text in %s, key is %s" % (fname , lair)
                    trophies += self.__smoke_out(lair)
        return trophies

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='louish, LibreOffice UI Strings Hunter')
    parser.add_argument('-s', '--string', help='(the text for which you want the usages', required=True)
    parser.add_argument('-f', '--file-selectors', help='(a list of space separated *.ext patterns - default: "*.hrc *.src *.ui"', required=False, default = '*.ui *.hrc *.src')
    args=vars(parser.parse_args())
    
    if not os.path.exists('.git'):
        raise Exception("We are not in a public git repository")
    
    h = hunter(args['string'], args['file_selectors'])
    if h.hunt():
        print h.show_trophies()
    else:
        print "Nothing found for %s" % args['string']


# vim: set et sw=4 ts=4:
