#!/usr/bin/env python3

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Copyright (C) Darren Hart <dvhart@linux.intel.com>, 2010


import sys
import getopt
import os
import os.path
import re

def usage():
    print('Usage: %s -d FILENAME [-d FILENAME]* -m METADIR [-m MATADIR]*' % os.path.basename(sys.argv[0]))
    print('  -d FILENAME         documentation file to search')
    print('  -h, --help          display this help and exit')
    print('  -m METADIR          meta directory to search for recipes')
    print('  -t FILENAME         documentation config file (for doc tags)')
    print('  -T                  Only display variables with doc tags (requires -t)')

def recipe_bbvars(recipe):
    ''' Return a unique set of every bbvar encountered in the recipe '''
    prog = re.compile("[A-Z_]+")
    vset = set()
    try:
        r = open(recipe)
    except IOError as err:
        print('WARNING: Failed to open recipe ', recipe)
        print(err.args[1])

    for line in r:
        # Strip any comments from the line
        line = line.rsplit('#')[0]
        vset = vset.union(set(prog.findall(line)))
    r.close()

    bbvars = {}
    for v in vset:
        bbvars[v] = 1

    return bbvars

def collect_bbvars(metadir):
    ''' Walk the metadir and collect the bbvars from each recipe found '''
    bbvars = {}
    for root,dirs,files in os.walk(metadir):
        for name in files:
            if name.find(".bb") >= 0:
                for key in recipe_bbvars(os.path.join(root,name)).keys():
                    if key in bbvars:
                        bbvars[key] = bbvars[key] + 1
                    else:
                        bbvars[key] = 1
    return bbvars

def bbvar_is_documented(var, docfiles):
    prog = re.compile(".*($|[^A-Z_])%s([^A-Z_]|$)" % (var))
    for doc in docfiles:
        try:
            f = open(doc)
        except IOError as err:
            print('WARNING: Failed to open doc ', doc)
            print(err.args[1])
        for line in f:
            if prog.match(line):
                return True
        f.close()
    return False

def bbvar_doctag(var, docconf):
    prog = re.compile('^%s\[doc\] *= *"(.*)"' % (var))
    if docconf == "":
        return "?"

    try:
        f = open(docconf)
    except IOError as err:
        return err.args[1]

    for line in f:
        m = prog.search(line)
        if m:
            return m.group(1)

    f.close()
    return ""

def main():
    docfiles = []
    metadirs = []
    bbvars = {}
    undocumented = []
    docconf = ""
    onlydoctags = False

    # Collect and validate input
    try:
        opts, args = getopt.getopt(sys.argv[1:], "d:hm:t:T", ["help"])
    except getopt.GetoptError as err:
        print('%s' % str(err))
        usage()
        sys.exit(2)

    for o, a in opts:
        if o in ('-h', '--help'):
            usage()
            sys.exit(0)
        elif o == '-d':
            if os.path.isfile(a):
                docfiles.append(a)
            else:
                print('ERROR: documentation file %s is not a regular file' % a)
                sys.exit(3)
        elif o == '-m':
            if os.path.isdir(a):
                metadirs.append(a)
            else:
                print('ERROR: meta directory %s is not a directory' % a)
                sys.exit(4)
        elif o == "-t":
            if os.path.isfile(a):
                docconf = a
        elif o == "-T":
            onlydoctags = True
        else:
            assert False, "unhandled option"

    if len(docfiles) == 0:
        print('ERROR: no docfile specified')
        usage()
        sys.exit(5)

    if len(metadirs) == 0:
        print('ERROR: no metadir specified')
        usage()
        sys.exit(6)

    if onlydoctags and docconf == "":
        print('ERROR: no docconf specified')
        usage()
        sys.exit(7)

    # Collect all the variable names from the recipes in the metadirs
    for m in metadirs:
        for key,cnt in collect_bbvars(m).items():
            if key in bbvars:
                bbvars[key] = bbvars[key] + cnt
            else:
                bbvars[key] = cnt

    # Check each var for documentation
    varlen = 0
    for v in bbvars.keys():
        if len(v) > varlen:
            varlen = len(v)
        if not bbvar_is_documented(v, docfiles):
            undocumented.append(v)
    undocumented.sort()
    varlen = varlen + 1

    # Report all undocumented variables
    print('Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars)))
    header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7))
    print(header)
    print(str("").ljust(len(header), '='))
    for v in undocumented:
        doctag = bbvar_doctag(v, docconf)
        if not onlydoctags or not doctag == "":
            print('%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag))


if __name__ == "__main__":
    main()
