# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utilities for working with code coverage files."""

import json
import logging
import os
from pathlib import Path
from typing import Dict, Iterable, List, Tuple

from chromite.lib import osutils


ZERO_COVERAGE_EXEC_COUNT = 0
ZERO_COVERAGE_START_COL = 1
LLVM_COVERAGE_JSON_TYPE = 'llvm.coverage.json.export'
LLVM_COVERAGE_VERSION = '2.0.1'


def _IsInstrumented(line: str, exclude_line_prefixes: Tuple[str]) -> bool:
  """Returns if the input line is instrumented or not.

    Method does a simple prefix based check to determine if
    a line is instrumendted or not.

  Args:
    line: Single code line to test for instrumentation.
    exclude_line_prefixes: tuple of un-instrumented line prefixes.

  Returns:
    True if the line is instrumented, otherwise false.
  """
  line = line.lstrip()
  if not line:
    return False
  return not line.startswith(tuple(exclude_line_prefixes))


def _CreateOpenSegment(line_number: int):
  """Create a segment corresponding to start of instrumented code region.

    Method to create and return a segment which represents start of an
    instrumented code region. For zero coverage purpose an open segment
    is always considered to start from col 1.

    More details about segments can be found here: go/chromeos-zero-coverage.

  Args:
    line_number: The line number from where the instrumented code region starts.

  Returns:
    An open segment.
  """
  return [
      line_number, ZERO_COVERAGE_START_COL, ZERO_COVERAGE_EXEC_COUNT, True,
      True, False
  ]


def _CreateCloseSegment(line_number: int, col: int):
  """Create a segment corresponding to end of instrumented code region.

    Method to create and return a segment which represents end of an
    instrumented code region.
    More details about segments can be found here: go/chromeos-zero-coverage.

  Args:
    line_number: Marks the end of instrumented code region.
    col: The col number which marks the end of the instrumented code region.

  Returns:
    A close segment.
  """
  return [line_number, col, ZERO_COVERAGE_EXEC_COUNT, False, False, False]


def _ExtractLlvmCoverageData(coverage_json: Dict) -> List:
  """Extract coverage data from coverage json.

  Args:
    coverage_json: llvm formatted coverage json.

  Returns:
    List of coverage data objects.
  """
  if (not coverage_json or not coverage_json.get('data')):
    return []

  return coverage_json['data'][0]['files']


def _GenerateZeroCoverageLLVMForFile(file_path: str, src_prefix_path: str,
                                     exclude_line_prefixes: Tuple[str]) -> Dict:
  """Generates LLVM json formatted zero % coverage for the given file.

    Method to identify all the instrumented lines within a file and generate
    mock coverage data json. The mock json marks all the instrumented lines
    as not-covered by unit tests.

    More detials: go/chromeos-zero-coverage.

  Args:
    file_path: path to the src file.
    src_prefix_path: prefix path for source code
    exclude_line_prefixes: Used to determine un-instrumented lines
    in the file.

  Returns:
    Dict representing zero coverage data for the file.
  """

  segments = []
  line_index = 0

  with open(file_path, 'r', encoding='utf8', errors='ignore') as file:

    lines = file.readlines()
    if not lines:
      return None

    while line_index < len(lines):
      # Search for next instrumented line
      while (line_index < len(lines) and
             not _IsInstrumented(lines[line_index], exclude_line_prefixes)):
        line_index += 1

      if line_index < len(lines):
        # Instrumented code block started. Add a open segment to indicate that
        segments.append(_CreateOpenSegment(line_index + 1))

      # Search for next un-instrumented line
      while (line_index < len(lines) and
             _IsInstrumented(lines[line_index], exclude_line_prefixes)):
        line_index += 1

      if line_index < len(lines):
        # Instrumented code block ended on previous line.
        # Add a close segment to indicate that
        segments.append(
            _CreateCloseSegment(line_index, len(lines[line_index - 1])))

    # If segment size is odd, this means there is an open instrumented
    # code block. Lets add a close segment.
    if len(segments) % 2 == 1:
      segments.append(
          _CreateCloseSegment(line_index, len(lines[line_index - 1])))

    file_data = {}
    file_data['filename'] = str(Path(file_path).relative_to(src_prefix_path))
    file_data['segments'] = segments
    # Zoss does not use summary field, so keep it empty
    file_data['summary'] = {}
    return file_data


def _ShouldExclude(file: str, exclude_files: List[str],
                   exclude_files_suffixes: Tuple[str],
                   extensions_to_remove_exclusion_check: Iterable[str]) -> bool:
  """Determine if the filename should be excluded from zero coverage.

    This method first does the suffixes based exclude check.
    Next it iterates over all |exclude_files| to search for |file|.
    Note that LLVM generated file paths are absolute paths, however
    |file| is relative to src.

    In cases where src files have llvm code coverage, but corresponding
    header files does not have llvm coverage, we need to exclude
    those header files from zero coverage. For checking if these header file
    are covered by llvm cov reports or not, rather than checking directly the
    filepath, remove the header extension and then check for the filepath
    presence in llvm cov reports.|extensions_to_remove_exclusion_check|
    contains these extensions such as header extension.

    Consider following example
    Assume LLVM cov contains reports for foo/google.cc but not for foo/google.h
    For deciding if zero cov should be generated for foo/google.h, don't just
    check if foo/google.h is included in llvm cov. Rather check if filename
    like foo/google is present in reports or not. If present, then don't
    generate zero cov for foo/google.h

  Args:
    file: Chromium src root relative file path.
    exclude_files: List of llvm generated file paths to exclude.
    exclude_files_suffixes: Used to exclude files based on suffixes
    extensions_to_remove_exclusion_check: Iterable of extensions to remove
      from a file path before exclusion check.

  Returns:
    True if a file should be excluded otherwise False.
  """
  should_exclude = False
  if file.endswith(exclude_files_suffixes):
    should_exclude = True
  else:
    temp_file = file

    for extension in extensions_to_remove_exclusion_check:
      if file.endswith(extension):
        temp_file = file[:-len(extension)]
        break

    for exclude_file in exclude_files:
      if temp_file in exclude_file:
        should_exclude = True
        break

  if should_exclude:
    logging.info('Excluding file %s from zero coverage generation.', file)
  return should_exclude


def GetLLVMCoverageWithFilesExcluded(coverage_json: Dict,
                                     exclude_files_suffixes: Tuple[str]
                                    ) -> Dict:
  """Removes and returns required file entries from coverage json.

     Method to remove file entries in coverage json which ends with one of
     the suffixes mentioned in |exclude_files_suffixes|.

  Args:
    coverage_json: llvm coverage json
    exclude_files_suffixes: Used to remove files based on suffixes

  Returns:
    llvm coverage json after required entries are removed.
  """
  if not exclude_files_suffixes:
    return coverage_json

  coverage_data = _ExtractLlvmCoverageData(coverage_json)
  result_coverage_data = []
  for entry in coverage_data:
    if not entry['filename'].endswith(exclude_files_suffixes):
      result_coverage_data.append(entry)
    else:
      logging.info('skipping file %s from zero coverage.',
                   entry['filename'])
  return CreateLlvmCoverageJson(result_coverage_data)


def MergeLLVMCoverageJson(coverage_json_1: Dict, coverage_json_2: Dict) -> Dict:
  """Merge coverage data of two coverage json and return single coverage json.

  Args:
    coverage_json_1: llvm coverage json to merge.
    coverage_json_2: llvm coverage json to merge.

  Returns:
    Single merged llvm formatted coverage json.
  """
  coverage_data_1 = _ExtractLlvmCoverageData(coverage_json_1)
  coverage_data_2 = _ExtractLlvmCoverageData(coverage_json_2)

  result = coverage_data_1.copy()
  result.extend(coverage_data_2)

  return CreateLlvmCoverageJson(result)


def ExtractFilenames(coverage_json: Dict) -> List[str]:
  """Extracts filenames from coverage json.

  Args:
    coverage_json: The coverage json in LLVM format.

  Returns:
    List of filenames.
  """
  if (not coverage_json or not coverage_json.get('data') or
      not coverage_json['data'][0].get('files')):
    return []

  files = coverage_json['data'][0]['files']
  filenames = []
  for file_data in files:
    filenames.append(file_data['filename'])

  return filenames


def CreateLlvmCoverageJson(coverage_data: List) -> Dict:
  """Given coverage_data, generate llvm format coverage json.

  Args:
    coverage_data: The coverage data containing array of file cov info.

  Returns:
    coverage json llvm format.
  """
  coverage_json = {
      'data': [{
          'files': coverage_data,
      }],
      'type': LLVM_COVERAGE_JSON_TYPE,
      'version': LLVM_COVERAGE_VERSION,
  }
  return coverage_json


def GenerateZeroCoverageLlvm(
    path_to_src_directories: List[str],
    src_file_extensions: List[str],
    exclude_line_prefixes: Tuple[str],
    exclude_files: List[str],
    exclude_files_suffixes: Tuple[str],
    src_prefix_path: str,
    extensions_to_remove_exclusion_check: Iterable[str]) -> Dict:
  """Generate zero coverage for all src files under  |path_to_src_directories|.

     More detials on how to generate zero coverage: go/chromeos-zero-coverage.

  Args:
    path_to_src_directories: Dir to look for files to generate zero coverage.
    src_file_extensions: Filter files based on these extensions.
    exclude_line_prefixes: Used to determine un-instrumented code.
    exclude_files: files to exclude from zero coverage.
    exclude_files_suffixes: Used to exclude files based on suffixes
    src_prefix_path: prefix path for source code
    extensions_to_remove_exclusion_check: Iterable of extensions to remove
      from a file path before exclusion check.

  Returns:
    llvm format coverage json.
  """
  coverage_data = []
  filenames = []
  for basedir in path_to_src_directories:
    for dirpath, _dirnames, filenames in os.walk(basedir):
      for filename in filenames:
        full_file_path = os.path.join(dirpath, filename)
        relative_file_path = full_file_path.replace(basedir, '')
        if (filename.endswith(tuple(src_file_extensions)) and
            not _ShouldExclude(relative_file_path, exclude_files,
                               exclude_files_suffixes,
                               extensions_to_remove_exclusion_check)):

          zero_cov = _GenerateZeroCoverageLLVMForFile(full_file_path,
                                                      src_prefix_path,
                                                      exclude_line_prefixes)

          if zero_cov:
            coverage_data.append(zero_cov)

  return CreateLlvmCoverageJson(coverage_data)


def GetLlvmJsonCoverageDataIfValid(path_to_file: str):
  """Gets the content of a file if it matches the llvm coverage json format.

  Args:
    path_to_file: The path of the file to read.

  Returns:
    The file contents if they match the llvm json structure, otherwise None.
  """
  try:
    # Only coverage.json files matter for llvm json coverage.
    if os.path.basename(path_to_file) != 'coverage.json':
      return None

    # Make sure the file exists.
    if not os.path.isfile(path_to_file):
      return None

    # Attempt to parse as json. It's fine for this to fail,
    # it means we can't manipulate it rather than an actual error.
    data = json.loads(osutils.ReadFile(path_to_file))

    # Validate the file structure is:
    # { data: [...], type: "..", version: "..." }.
    if 'data' not in data or 'type' not in data or 'version' not in data:
      return None

    if data['type'] != 'llvm.coverage.json.export':
      return None

    return data
  except Exception as e:
    logging.warning('GetLlvmJsonCoverageDataIfValid failed %s', e)
    return None
