#!/usr/bin/env python
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

import os
import re
import string

# TARGET_RE matches a GN target, and extracts the target name and the contents.
TARGET_RE = re.compile(
    r'(?P<indent>\s*)\w+\("(?P<target_name>\w+)"\) {'
    r'(?P<target_contents>.*?)'
    r'(?P=indent)}', re.MULTILINE | re.DOTALL)

# SOURCES_RE matches a block of sources inside a GN target.
SOURCES_RE = re.compile(
    r'(sources|public|common_objc_headers) \+?= \[(?P<sources>.*?)\]',
    re.MULTILINE | re.DOTALL)

SOURCE_FILE_RE = re.compile(r'.*\"(?P<source_file>.*)\"')


class NoBuildGnFoundError(Exception):
    pass


class WrongFileTypeError(Exception):
    pass


def _ReadFile(file_path):
    """Returns the content of file_path in a string.

  Args:
    file_path: the path of the file to read.
  Returns:
    A string with the content of the file.
  """
    with open(file_path) as f:
        return f.read()


def GetBuildGnPathFromFilePath(file_path, file_exists_check, root_dir_path):
    """Returns the BUILD.gn file responsible for file_path.

  Args:
    file_path: the absolute path to the .h file to check.
    file_exists_check: a function that defines how to check if a file exists
      on the file system.
    root_dir_path: the absolute path of the root of project.

  Returns:
    A string with the absolute path to the BUILD.gn file responsible to include
    file_path in a target.
  """
    if not file_path.endswith('.h'):
        raise WrongFileTypeError(
            'File {} is not an header file (.h)'.format(file_path))
    candidate_dir = os.path.dirname(file_path)
    while candidate_dir.startswith(root_dir_path):
        candidate_build_gn_path = os.path.join(candidate_dir, 'BUILD.gn')
        if file_exists_check(candidate_build_gn_path):
            return candidate_build_gn_path
        else:
            candidate_dir = os.path.abspath(
                os.path.join(candidate_dir, os.pardir))
    raise NoBuildGnFoundError(
        'No BUILD.gn file found for file: `{}`'.format(file_path))


def IsHeaderInBuildGn(header_path, build_gn_path):
    """Returns True if the header is listed in the BUILD.gn file.

  Args:
    header_path: the absolute path to the header to check.
    build_gn_path: the absolute path to the header to check.

  Returns:
    bool: True if the header_path is an header that is listed in
      at least one GN target in the BUILD.gn file specified by
      the argument build_gn_path.
  """
    target_abs_path = os.path.dirname(build_gn_path)
    build_gn_content = _ReadFile(build_gn_path)
    headers_in_build_gn = GetHeadersInBuildGnFileSources(
        build_gn_content, target_abs_path)
    return header_path in headers_in_build_gn


def GetHeadersInBuildGnFileSources(file_content, target_abs_path):
    """Returns a set with all the .h files in the file_content.

  Args:
    file_content: a string with the content of the BUILD.gn file.
    target_abs_path: the absolute path to the directory where the
      BUILD.gn file lives.

  Returns:
    A set with all the headers (.h file) in the file_content.
    The set contains absolute paths.
  """
    headers_in_sources = set([])
    for target_match in TARGET_RE.finditer(file_content):
        target_contents = target_match.group('target_contents')
        for sources_match in SOURCES_RE.finditer(target_contents):
            sources = sources_match.group('sources')
            for source_file_match in SOURCE_FILE_RE.finditer(sources):
                source_file = source_file_match.group('source_file')
                if source_file.endswith('.h'):
                    source_file_tokens = string.split(source_file, '/')
                    headers_in_sources.add(
                        os.path.join(target_abs_path, *source_file_tokens))
    return headers_in_sources
