#!/usr/bin/env python2

"""Zephyr Check kconfigs Definitions

Check all CONFIG_* in the code are defined into a Kconfig file

usage: checkconfig.py [-h] [-k KCONFIG] [-c] [-e EXCLUDE]

"""

import sys
import os
import re
import argparse
from argparse import SUPPRESS

help_text="""
Checkconfig script scans all '*.c', '*.h' and '*.S' looking for all kconfig
items used in the Zephyr Code and validates if they are defined in any
'*.kconfig*' file.

To run script use command:

checkconfig.py [-h|--help] [-c|--complete-log] [-k|--kconfig <kconfig>]
               [-e|--exclude <dir_to_exclude>]

It will send to output:
-config name
-location where config is used
-full line where the config is being used
-location were config is being defined (there could be multiple declarations)

    [-c|--complete-log] is an optional parameter.
    If it is not given it will print only the kconfigs not defined
    If given, it will print all the kconfigs found

    [-s|--subdir <subdir>] is an optional parameter.
    When a directory is given it will start scan from that specific directorywith .
    By default it scans from zephyr base tree

    [-e|--exclude <subdir_to_exclude>] is an optional parameter.
    When a subdirectory is given it will be appended to defaut exclude dirs list.
    Default exclude dirs are: "doc", "sanity-out" and "outdir"
"""

#the genrest dir contains kconfiglib.py
zephyrbase = os.environ.get('ZEPHYR_BASE')

if zephyrbase == None:
    print ("env. variable ZEPHYR_BASE is not set, "
           "ensure you have source zephyr-env.sh")
    exit(1)
elif not os.path.exists(zephyrbase):
    print ("env. variable ZEPHYR_BASE \""+ zephyrbase +
           "\" does not exist as a valid zephyr base directory")
    exit(1)

os.environ['srctree'] = os.path.join(zephyrbase + os.path.sep)
sys.path.append(os.path.join(zephyrbase,'doc','scripts','genrest'))

import kconfiglib

def separate_location_lines(dirs):
    for dir in dirs:
        print "    ", dir

def search_kconfig_items(items, name, completelog):
    findConfig = False
    for item in items:
        if item.is_symbol():
            if (item.get_name() == name):
                if (completelog == True):
                    separate_location_lines(item.get_def_locations())
                findConfig = True
                break

        elif item.is_menu():
            if search_kconfig_items(item.get_items(), name, completelog):
                return True

        elif item.is_choice():
            if search_kconfig_items(item.get_items(), name, completelog):
                return True

        elif item.is_comment():
            if (item.get_text() == name):
                print completelog
                if (completelog == True):
                    separate_location_lines(item.get_location())
                findConfig = True
                break
    return findConfig

def search_config_in_file(tree, items, completelog, exclude):
    configs = 0
    notdefConfig = 0
    for dirName, subdirs, files in os.walk(tree, topdown=True):
        subdirs[:] = [d for d in subdirs if d not in exclude]
        for fname in files:
            if (fname.endswith(".c") or
            fname.endswith(".h") or
            fname.endswith(".S")):
                with open(os.path.join(dirName, fname), "r") as f:
                    searchConf = f.readlines()
                for i, line in enumerate(searchConf):
                    if re.search('(^|[\s|(])CONFIG_([a-zA-Z0-9_]+)', line) :
                        configName = re.search('(^|[\s|(])'
                                               +'CONFIG_([a-zA-Z0-9_]+)', line)
                        configs = configs + 1
                        if (completelog == True):
                            print ('\n' + configName.group(2) + ' at '
                                   + os.path.join(dirName, fname))
                            print 'line: ' + line.rstrip()
                        find = search_kconfig_items(items, configName.group(2),
                                                    completelog)
                        if (find == False):
                            print ('\n' + configName.group(2) + ' at '
                                   + os.path.join(dirName, fname)
                                   + ' IS NOT DEFINED')
                            print 'line: ' + line.rstrip()
                            notdefConfig = notdefConfig + 1
    if (completelog == True):
        print "\n{} Kconfigs evaluated".format(configs)
        print "{} Kconfigs not defined".format(notdefConfig)

parser = argparse.ArgumentParser(description = help_text,
                                 usage = SUPPRESS,
                                 formatter_class = argparse.RawTextHelpFormatter)
parser.add_argument('-s', '--subdir', action='store', dest='subdir',
                    default="",
                    help='sub directory to be scanned')
parser.add_argument('-c', '--complete-log', action='store_true',
                    dest='completelog', default=False,
                    help='Prints all the kconfigs found')
parser.add_argument('-e', '--exclude', action='append', dest='exclude',
                    default=["doc", "sanity-out", "outdir"],
                    help='Dirs to be excluded for verification')

args= parser.parse_args()
if args.completelog:
    print 'sub dir      = ', os.path.join(zephyrbase + args.subdir)
    print 'complete-log = ', args.completelog
    print 'exclude dirs = ', args.exclude

conf = kconfiglib.Config(os.path.join(zephyrbase,'Kconfig'))
search_config_in_file(os.path.join(zephyrbase + os.path.sep + args.subdir),
                      conf.get_top_level_items(), args.completelog, args.exclude)
