#!/usr/bin/env python3
# Copyright 2021 The Pigweed 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
#
#     https://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.
"""Invoke clang-tidy.

Implements additional features compared to directly calling
clang-tidy:
  - add option `--source-exclude` to exclude matching sources from the
    clang-tidy analysis.
  - inputs the full compile command, with the cc binary name
  - TODO: infer platform options from the full compile command
"""

import argparse
import logging
from pathlib import Path
import shlex
import subprocess
import sys
from typing import Iterable, List, Optional, Union

_LOG = logging.getLogger(__name__)


def _parse_args() -> argparse.Namespace:
    """Parses arguments for this script, splitting out the command to run."""

    parser = argparse.ArgumentParser()
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Run clang_tidy with extra debug output.')

    parser.add_argument('--clang-tidy',
                        default='clang-tidy',
                        help='Path to clang-tidy executable.')

    parser.add_argument(
        '--source-file',
        required=True,
        type=Path,
        help='Path to the source file to analyze with clang-tidy.')
    parser.add_argument(
        '--source-root',
        required=True,
        type=Path,
        help=('Path to the root source directory.'
              ' The relative path from the root directory is matched'
              ' against source filter rather than the absolute path.'))
    parser.add_argument(
        '--export-fixes',
        required=False,
        type=Path,
        help=('YAML file to store suggested fixes in. The '
              'stored fixes can be applied to the input source '
              'code with clang-apply-replacements.'))

    parser.add_argument('--source-exclude',
                        default=[],
                        action='append',
                        type=str,
                        help=('Glob-style patterns matching the paths of'
                              ' source files to be excluded from the'
                              ' analysis.'))

    parser.add_argument(
        '--skip-include-path',
        default=[],
        nargs='*',
        help=('Exclude include paths ending in these paths from clang-tidy. '
              'These paths are switched from -I to -isystem so clang-tidy '
              'ignores them.'))

    # Add a silent placeholder arg for everything that was left over.
    parser.add_argument('extra_args',
                        nargs=argparse.REMAINDER,
                        help=argparse.SUPPRESS)

    parsed_args = parser.parse_args()

    if parsed_args.extra_args[0] != '--':
        parser.error('arguments not correctly split')

    parsed_args.extra_args = parsed_args.extra_args[1:]
    return parsed_args


def _filter_include_paths(args: Iterable[str],
                          skip_include_paths: Iterable[str]) -> Iterable[str]:
    filters = [f.rstrip('/') for f in skip_include_paths]

    for arg in args:
        if arg.startswith('-I'):
            path = Path(arg[2:]).as_posix()
            if any(path.endswith(f) for f in filters):
                yield '-isystem' + arg[2:]
                continue

        yield arg


def run_clang_tidy(clang_tidy: str, verbose: bool, source_file: Path,
                   export_fixes: Optional[Path], skip_include_path: List[str],
                   extra_args: List[str]) -> int:
    """Executes clang_tidy via subprocess. Returns true if no failures."""
    command: List[Union[str, Path]] = [clang_tidy, source_file, '--use-color']

    if not verbose:
        command.append('--quiet')

    if export_fixes is not None:
        command.extend(['--export-fixes', export_fixes])

    # Append extra compilation flags. extra_args[0] is skipped as it contains
    # the compiler binary name.
    command.append('--')
    command.extend(_filter_include_paths(extra_args[1:], skip_include_path))

    process = subprocess.run(
        command,
        stdout=subprocess.PIPE,
        # clang-tidy prints regular information on
        # stderr, even with the option --quiet.
        stderr=subprocess.PIPE)

    if process.returncode != 0:
        _LOG.warning('%s', ' '.join(shlex.quote(str(arg)) for arg in command))

    if process.stdout:
        _LOG.warning(process.stdout.decode().strip())

    if process.stderr and process.returncode != 0:
        _LOG.error(process.stderr.decode().strip())

    return process.returncode


def main(
    verbose: bool,
    clang_tidy: str,
    source_file: Path,
    source_root: Path,
    export_fixes: Optional[Path],
    source_exclude: List[str],
    skip_include_path: List[str],
    extra_args: List[str],
) -> int:
    # Rebase the source file path on source_root.
    # If source_file is not relative to source_root (which may be the case for
    # generated files) stick with the original source_file.
    try:
        relative_source_file = source_file.relative_to(source_root)
    except ValueError:
        relative_source_file = source_file

    for pattern in source_exclude:
        if relative_source_file.match(pattern):
            return 0

    source_file_path = source_file.resolve()
    export_fixes_path = (export_fixes.resolve()
                         if export_fixes is not None else None)
    return run_clang_tidy(clang_tidy, verbose, source_file_path,
                          export_fixes_path, skip_include_path, extra_args)


if __name__ == '__main__':
    sys.exit(main(**vars(_parse_args())))
