#!/usr/bin/env python3.8
# Copyright 2016 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to check C and C++ file header guards.

This script accepts a list of file or directory arguments. If a given
path is a file, it runs the checker on it. If the path is a directory,
it runs the checker on all files in that directory.

In addition, this script checks for potential header guard
collisions. This is useful since we munge / to _, and so
    lib/abc/xyz/xyz.h
and
    lib/abc_xyz/xyz.h
both want to use LIB_ABC_XYZ_XYZ_H_ as a header guard.

"""

import argparse
import collections
import fileinput
import os.path
import re
import string
import sys

FUCHSIA_ROOT = os.path.dirname(  # $root
    os.path.dirname(             # scripts
    os.path.dirname(             # style
    os.path.realpath(
    os.path.abspath(__file__)))))

SYSROOT_PREFIXES = [
    'ZIRCON_SYSTEM_PUBLIC',
    'ZIRCON_THIRD_PARTY_ULIB_MUSL_INCLUDE',
]
sysroot_prefix = re.compile('^(' + '|'.join(SYSROOT_PREFIXES) + ')_')

PUBLIC_PREFIXES = ['ZIRCON_SYSTEM_ULIB_.*_INCLUDE', 'SDK']
public_prefix = re.compile('^(' + '|'.join(PUBLIC_PREFIXES) + ')_')

all_header_guards = collections.defaultdict(list)

pragma_once = re.compile('^#pragma once$')
disallowed_header_characters = re.compile('[^a-zA-Z0-9_]')


def adjust_for_location(header_guard):
    """Remove internal location prefix from public headers if applicable."""
    # Remove public prefixes
    header_guard = public_prefix.sub('', header_guard, 1)
    # Replace sysroot prefixes
    header_guard = sysroot_prefix.sub('SYSROOT_', header_guard, 1)

    return header_guard


def header_guard_from_path(path):
    """Compute the header guard from the path"""
    assert (path.startswith(FUCHSIA_ROOT))
    relative_path = path[len(FUCHSIA_ROOT):].strip('/')
    upper_path = relative_path.upper()
    header_guard = re.sub(disallowed_header_characters, '_', upper_path) + '_'
    header_guard = adjust_for_location(header_guard)
    return header_guard


def check_file(path, fix_guards=False):
    """Check whether the file has a correct header guard.

    A header guard can either be a #pragma once, or else a matching set of
        #ifndef PATH_TO_FILE_
        #define PATH_TO_FILE_
        ...
        #endif  // PATH_TO_FILE_
    preprocessor directives, where both '.' and '/' in the path are
    mapped to '_', and a trailing '_' is appended.

    In either the #pragma once case or the header guard case, it is
    assumed that there is no trailing or leading whitespace.

    """

    # Only check .h files
    if path[-2:] != '.h':
        return True

    header_guard = header_guard_from_path(path)
    all_header_guards[header_guard].append(path)

    ifndef = re.compile('^#ifndef %s$' % header_guard)
    define = re.compile('^#define %s$' % header_guard)
    endif = re.compile('^#endif +// *%s$' % header_guard)

    found_pragma_once = False
    found_ifndef = False
    found_define = False
    found_endif = False

    with open(path, 'r') as f:
        for line in f.readlines():
            match = pragma_once.match(line)
            if match:
                if found_pragma_once:
                    print('%s contains multiple #pragma once' % path)
                    return False
                found_pragma_once = True

            match = ifndef.match(line)
            if match:
                if found_ifndef:
                    print('%s contains multiple ifndef header guards' % path)
                    return False
                found_ifndef = True

            match = define.match(line)
            if match:
                if found_define:
                    print('%s contains multiple define header guards' % path)
                    return False
                found_define = True

            match = endif.match(line)
            if match:
                if found_endif:
                    print('%s contains multiple endif header guards' % path)
                    return False
                found_endif = True

    if found_pragma_once:
        if found_ifndef or found_define or found_endif:
            print('%s contains both #pragma once and header guards' % path)
            return False
        if not fix_guards:
            return True

    if found_ifndef and found_define and found_endif:
        return True

    if not found_ifndef:
        print('%s did not contain ifndef part of its header guard' % path)
    elif not found_define:
        print('%s did not contain define part of its header guard' % path)
    elif not found_endif:
        print('%s did not contain endif part of its header guard' % path)
    elif fix_guards:
        if found_pragma_once:
            print('%s contained #pragma once instead of a header guard' % path)
        else:
            print(
                '%s did not contain a header guard or the header guard did '
                'not match the file path' % path)
    else:
        print(
            '%s contained neither a proper header guard nor #pragma once' %
            path)

    header_guards_fixed = False
    if fix_guards:
        header_guards_fixed = fix_header_guard(path, header_guard)

    if not header_guards_fixed:
        print(
            'Allowable header guard values are %s' %
            list(all_header_guards.keys()))

    return False


def fix_header_guard(path, header_guard):
    """Attempt to fix the header guard in the given file."""
    ifndef = re.compile('^#ifndef [^\s]+_H_$')
    define = re.compile('^#define [^\s]+_H_$')
    endif = re.compile('^#endif +// *[^\s]+_H_$')
    fixed_ifndef = False
    fixed_define = False
    fixed_endif = False
    fixed_pragma_once = False

    for line in fileinput.input(path, inplace=1):
        (new_line, changes) = re.subn(ifndef, '#ifndef %s' % header_guard, line)
        if changes:
            fixed_ifndef = True
            sys.stdout.write(new_line)
            continue
        (new_line, changes) = re.subn(define, '#define %s' % header_guard, line)
        if changes:
            fixed_define = True
            sys.stdout.write(new_line)
            continue
        (new_line,
         changes) = re.subn(endif, '#endif  // %s' % header_guard, line)
        if changes:
            fixed_endif = True
            sys.stdout.write(new_line)
            continue
        if pragma_once.match(line):
            fixed_pragma_once = True
            sys.stdout.write('#ifndef %s\n' % header_guard)
            sys.stdout.write('#define %s\n' % header_guard)
            continue
        sys.stdout.write(line)

    if fixed_pragma_once:
        with open(path, 'a') as file:
            file.write('\n')
            file.write('#endif  // %s\n' % header_guard)

    if (fixed_ifndef and fixed_define and fixed_endif) or fixed_pragma_once:
        print('Fixed!')
        return True

    print('Not fixed...')
    return False


def check_dir(p, fix_guards=False):
    """Walk recursively over a directory checking .h files"""

    def prune(d):
        if d[0] == '.' or d == 'third_party':
            return True
        return False

    for root, dirs, paths in os.walk(p):
        # Prune dot directories like .git
        [dirs.remove(d) for d in list(dirs) if prune(d)]
        for path in paths:
            check_file(os.path.join(root, path), fix_guards=fix_guards)


def check_collisions():
    for header_guard, paths in all_header_guards.items():
        if len(paths) == 1:
            continue
        print('Multiple files could use %s as a header guard:' % header_guard)
        for path in paths:
            print('    %s' % path)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--fix', help='Correct wrong header guards', action='store_true')
    (arg_results, other_args) = parser.parse_known_args()
    fix_guards = arg_results.fix
    for p in other_args:
        p = os.path.realpath(os.path.abspath(p))
        if os.path.isdir(p):
            check_dir(p, fix_guards=fix_guards)
        else:
            check_file(p, fix_guards=fix_guards)
    check_collisions()


if __name__ == "__main__":
    sys.exit(main())
