#!/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
