#!/usr/bin/env python3

# Copyright 2022 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import os
import os.path
import re
import subprocess
import sys

# TODO(hork): dedupe args/load/validate/save code with other check scripts.


def load(fpath):
    with open(fpath, "r") as f:
        return f.readlines()


def save(fpath, contents):
    with open(fpath, "w") as f:
        f.write(contents)


class QualificationValidator(object):
    def __init__(self):
        self.fully_qualified_re = re.compile(r"([ (<])::(grpc[A-Za-z_:])")
        self.using_re = re.compile(
            r"(using +|using +[A-Za-z_]+ *= *|namespace [A-Za-z_]+ *= *)::"
        )
        self.define_re = re.compile(r"^#define")

    def check(self, fpath, fix):
        fcontents = load(fpath)
        failed = False
        for i, line in enumerate(fcontents):
            if not self.fully_qualified_re.search(line):
                continue
            # skip `using` statements
            if self.using_re.search(line):
                continue
            # skip `#define` statements
            if self.define_re.search(line):
                continue
            # fully-qualified namespace found, which may be unnecessary
            if fix:
                fcontents[i] = self.fully_qualified_re.sub(r"\1\2", line)
            else:
                print("Found in %s:%d - %s" % (fpath, i, line.strip()))
                failed = True
        if fix:
            save(fpath, "".join(fcontents))
        return not failed


IGNORED_FILES = [
    # TODO(hork): rename symbols to avoid the need for fully-qualified names
    "src/cpp/common/core_codegen.cc",
    # TODO(hork): This could be a breaking change for users that define their
    # own (possibly nested) `grpc.*` namespaces that contain conflicting
    # symbols. It may be worth trying to land this change at some point, as
    # users would be better off using unique namespaces.
    "src/compiler/cpp_generator.cc",
    # multi-line #define statements are not handled
    "src/core/lib/gprpp/global_config_env.h",
    "src/core/lib/profiling/timers.h",
    "src/core/lib/gprpp/crash.h",
]

# find our home
ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
os.chdir(ROOT)

# parse command line
argp = argparse.ArgumentParser(
    description="c++ namespace full qualification checker"
)
argp.add_argument("-f", "--fix", default=False, action="store_true")
argp.add_argument("--precommit", default=False, action="store_true")
args = argp.parse_args()

grep_filter = r"grep -E '^(include|src|test).*\.(h|cc)$'"
if args.precommit:
    git_command = "git diff --name-only HEAD"
else:
    git_command = "git ls-tree -r --name-only -r HEAD"

FILE_LIST_COMMAND = " | ".join((git_command, grep_filter))

# scan files
ok = True
filename_list = []
try:
    filename_list = (
        subprocess.check_output(FILE_LIST_COMMAND, shell=True)
        .decode()
        .splitlines()
    )
    # Filter out non-existent files (ie, file removed or renamed)
    filename_list = (f for f in filename_list if os.path.isfile(f))
except subprocess.CalledProcessError:
    sys.exit(0)

validator = QualificationValidator()

for filename in filename_list:
    # Skip check for upb generated code and ignored files.
    if (
        filename.endswith(".upb.h")
        or filename.endswith(".upbdefs.h")
        or filename.endswith(".upbdefs.c")
        or filename in IGNORED_FILES
    ):
        continue
    ok = validator.check(filename, args.fix) and ok

sys.exit(0 if ok else 1)
