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

import difflib
import os
import sys

from util import build_utils
import action_helpers  # build_utils adds //build to sys.path.


def _SkipOmitted(line):
  """
  Skip lines that are to be intentionally omitted from the expectations file.

  This is required when the file to be compared against expectations contains
  a line that changes from build to build because - for instance - it contains
  version information.
  """
  if line.rstrip().endswith('# OMIT FROM EXPECTATIONS'):
    return '# THIS LINE WAS OMITTED\n'
  return line


def _GenerateDiffWithOnlyAdditons(expected_path, actual_data):
  """Generate a diff that only contains additions"""
  # Ignore blank lines when creating the diff to cut down on whitespace-only
  # lines in the diff. Also remove trailing whitespaces and add the new lines
  # manually (ndiff expects new lines but we don't care about trailing
  # whitespace).
  with open(expected_path) as expected:
    expected_lines = [l for l in expected.readlines() if l.strip()]
  actual_lines = [
      '{}\n'.format(l.rstrip()) for l in actual_data.splitlines() if l.strip()
  ]

  # This helps the diff to not over-anchor on comments or closing braces in
  # proguard configs.
  def is_junk_line(l):
    l = l.strip()
    if l.startswith('# File:'):
      return False
    return l == '' or l == '}' or l.startswith('#')

  diff = difflib.ndiff(expected_lines, actual_lines, linejunk=is_junk_line)
  filtered_diff = (l for l in diff if l.startswith('+'))
  return ''.join(filtered_diff)


def _DiffFileContents(expected_path, actual_data):
  """Check file contents for equality and return the diff or None."""
  # Remove all trailing whitespace and add it explicitly in the end.
  with open(expected_path) as f_expected:
    expected_lines = [l.rstrip() for l in f_expected.readlines()]
  actual_lines = [
      _SkipOmitted(line).rstrip() for line in actual_data.splitlines()
  ]

  if expected_lines == actual_lines:
    return None

  expected_path = os.path.relpath(expected_path, build_utils.DIR_SOURCE_ROOT)

  diff = difflib.unified_diff(
      expected_lines,
      actual_lines,
      fromfile=os.path.join('before', expected_path),
      tofile=os.path.join('after', expected_path),
      n=0,
      lineterm='',
  )

  return '\n'.join(diff)


def AddCommandLineFlags(parser):
  group = parser.add_argument_group('Expectations')
  group.add_argument(
      '--expected-file',
      help='Expected contents for the check. If --expected-file-base  is set, '
      'this is a diff of --actual-file and --expected-file-base.')
  group.add_argument(
      '--expected-file-base',
      help='File to diff against before comparing to --expected-file.')
  group.add_argument('--actual-file',
                     help='Path to write actual file (for reference).')
  group.add_argument('--failure-file',
                     help='Write to this file if expectations fail.')
  group.add_argument('--fail-on-expectations',
                     action="store_true",
                     help='Fail on expectation mismatches.')
  group.add_argument('--only-verify-expectations',
                     action='store_true',
                     help='Verify the expectation and exit.')


def CheckExpectations(actual_data, options, custom_msg=''):
  if options.actual_file:
    with action_helpers.atomic_output(options.actual_file) as f:
      f.write(actual_data.encode('utf8'))
  if options.expected_file_base:
    actual_data = _GenerateDiffWithOnlyAdditons(options.expected_file_base,
                                                actual_data)
  diff_text = _DiffFileContents(options.expected_file, actual_data)

  if not diff_text:
    fail_msg = ''
  else:
    fail_msg = """
Expectations need updating:
https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/android/expectations/README.md

LogDog tip: Use "Raw log" or "Switch to lite mode" before copying:
https://bugs.chromium.org/p/chromium/issues/detail?id=984616

{}

To update expectations, run:
########### START ###########
 patch -p1 <<'END_DIFF'
{}
END_DIFF
############ END ############
""".format(custom_msg, diff_text)

    sys.stderr.write(fail_msg)

  if fail_msg and options.fail_on_expectations:
    # Don't write failure file when failing on expectations or else the target
    # will not be re-run on subsequent ninja invocations.
    sys.exit(1)

  if options.failure_file:
    with open(options.failure_file, 'w') as f:
      f.write(fail_msg)
