# Lint as: python2, python3
# Copyright 2020 The Bazel Authors. All rights reserved.
#
# 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
#
#    http://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.
r"""Command line diffing tool that compares two bazel aquery invocations.

This makes use of aquery v2 proto format.

This script compares the proto or textproto output of two bazel aquery
invocations. For each set of output files of an action, it compares the command
lines that generated the files.

Example usage:

1. Prepare 2 aquery output files:
bazel aquery //path/to:target_one --output=textproto > \
    /path/to/output_one.textproto
bazel aquery //path/to:target_two --output=textproto > \
    /path/to/output_two.textproto

2. Run the differ from a bazel repo:
bazel run //tools/aquery_differ:aquery_differ_v2 -- \
--before=/path/to/output_one.textproto \
--after=/path/to/output_two.textproto \
--input_type=textproto \
--attrs=cmdline \
--attrs=inputs
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import difflib
import os
import sys

# Do not edit this line. Copybara replaces it with PY2 migration helper.
from absl import app
from absl import flags
from six.moves import map
from google.protobuf import text_format
from src.main.protobuf import analysis_v2_pb2
from tools.aquery_differ.resolvers.dep_set_resolver import DepSetResolver
from tools.aquery_differ.resolvers.path_fragment_resolver import PathFragmentResolver

flags.DEFINE_string("before", None, "Aquery output before the change")
flags.DEFINE_string("after", None, "Aquery output after the change")
flags.DEFINE_enum(
    "input_type", "proto", ["proto", "textproto"],
    "The format of the aquery proto input. One of 'proto' and 'textproto.")
flags.DEFINE_multi_enum("attrs", ["cmdline"], ["inputs", "cmdline"],
                        "Attributes of the actions to be compared.")
flags.mark_flag_as_required("before")
flags.mark_flag_as_required("after")

WHITE = "\033[37m%s\033[0m"
CYAN = "\033[36m%s\033[0m"
RED = "\033[31m%s\033[0m"
GREEN = "\033[32m%s\033[0m"


def _colorize(line):
  """Add color to the input string."""
  if not sys.stdout.isatty():
    return line

  if line.startswith("+++") or line.startswith("---"):
    return WHITE % line

  if line.startswith("@@"):
    return CYAN % line

  if line.startswith("+"):
    return GREEN % line

  if line.startswith("-"):
    return RED % line

  return line


def _print_diff(output_files, before_val, after_val, attr, before_file,
                after_file):
  diff = "\n".join(
      map(_colorize, [
          s.strip("\n") for s in difflib.unified_diff(before_val, after_val,
                                                      before_file, after_file)
      ]))
  print(("[%s]\n"
         "Difference in the action that generates the following output(s):"
         "\n\t%s\n%s\n") % (attr, "\n\t".join(output_files.split()), diff))


def _map_artifact_id_to_path(artifacts, path_fragments):
  path_fragment_resolver = PathFragmentResolver(path_fragments)
  return {
      artifact.id: path_fragment_resolver.resolve(artifact.path_fragment_id)
      for artifact in artifacts
  }


def _map_action_index_to_output_files(actions, artifacts):
  """Constructs a map from action index to output files.

  Args:
    actions: a list of actions from the action graph container
    artifacts: a map {artifact_id: artifact path}

  Returns:
    A map from action index (in action graph container) to a string of
    concatenated output artifacts paths.
  """
  action_index_to_output_files = {}
  for i, action in enumerate(actions):
    output_files = " ".join(
        sorted([artifacts[output_id] for output_id in action.output_ids]))
    action_index_to_output_files[i] = output_files
  return action_index_to_output_files


# output files -> input artifacts
def _map_output_files_to_input_artifacts(action_graph_container,
                                         artifact_id_to_path,
                                         action_index_to_output_files):
  """Constructs a map from output files to input artifacts.

  Args:
    action_graph_container: the full action graph container object
    artifact_id_to_path: a map {artifact_id: artifact path}
    action_index_to_output_files: a map from action index (in action graph
      container) to a string of concatenated output artifacts paths.

  Returns:
    A map from output files (string of concatenated output artifacts paths) to a
    list of input artifacts.
  """
  actions = action_graph_container.actions
  dep_set_of_files = action_graph_container.dep_set_of_files
  id_to_dep_set = {dep_set.id: dep_set for dep_set in dep_set_of_files}
  dep_set_resolver = DepSetResolver(dep_set_of_files, artifact_id_to_path)

  output_files_to_input_artifacts = {}
  for i, action in enumerate(actions):
    input_artifacts = []

    for dep_set_id in action.input_dep_set_ids:
      input_artifacts.extend(
          dep_set_resolver.resolve(id_to_dep_set[dep_set_id]))

    output_files_to_input_artifacts[action_index_to_output_files[i]] = list(
        sorted(input_artifacts))

  return output_files_to_input_artifacts


# output files -> command line
def _map_output_files_to_command_line(actions, action_index_to_output_files):
  """Constructs a map from output files to command line.

  Args:
    actions: a list of actions from the action graph container
    action_index_to_output_files: a map from action index (in action graph
      container) to a string of concatenated output artifacts paths.

  Returns:
    A map from output files (string of concatenated output artifacts paths)
    to the command line (a list of arguments).
  """
  output_files_to_command_line = {}
  for i, action in enumerate(actions):
    output_files_to_command_line[
        action_index_to_output_files[i]] = action.arguments
  return output_files_to_command_line


def _aquery_diff(before_proto, after_proto, attrs, before_file, after_file):
  """Returns differences between command lines that generate same outputs."""
  found_difference = False
  artifacts_before = _map_artifact_id_to_path(before_proto.artifacts,
                                              before_proto.path_fragments)
  artifacts_after = _map_artifact_id_to_path(after_proto.artifacts,
                                             after_proto.path_fragments)

  action_to_output_files_before = _map_action_index_to_output_files(
      before_proto.actions, artifacts_before)
  action_to_output_files_after = _map_action_index_to_output_files(
      after_proto.actions, artifacts_after)

  # There's a 1-to-1 mapping between action and outputs
  output_files_before = set(action_to_output_files_before.values())
  output_files_after = set(action_to_output_files_after.values())

  before_after_diff = output_files_before - output_files_after
  after_before_diff = output_files_after - output_files_before

  if before_after_diff:
    print(("Aquery output 'before' change contains an action that generates "
           "the following outputs that aquery output 'after' change doesn't:"
           "\n%s\n") % "\n".join(before_after_diff))
    found_difference = True
  if after_before_diff:
    print(("Aquery output 'after' change contains an action that generates "
           "the following outputs that aquery output 'before' change doesn't:"
           "\n%s\n") % "\n".join(after_before_diff))
    found_difference = True

  if "cmdline" in attrs:
    output_to_command_line_before = _map_output_files_to_command_line(
        before_proto.actions, action_to_output_files_before)
    output_to_command_line_after = _map_output_files_to_command_line(
        after_proto.actions, action_to_output_files_after)
    for output_files in output_to_command_line_before:
      arguments = output_to_command_line_before[output_files]
      after_arguments = output_to_command_line_after.get(output_files, None)
      if after_arguments and arguments != after_arguments:
        _print_diff(output_files, arguments, after_arguments, "cmdline",
                    before_file, after_file)
        found_difference = True

  if "inputs" in attrs:
    output_to_input_files_before = _map_output_files_to_input_artifacts(
        before_proto, artifacts_before, action_to_output_files_before)
    output_to_input_files_after = _map_output_files_to_input_artifacts(
        after_proto, artifacts_after, action_to_output_files_after)
    for output_files in output_to_input_files_before:
      before_inputs = output_to_input_files_before[output_files]
      after_inputs = output_to_input_files_after.get(output_files, None)
      if after_inputs and before_inputs != after_inputs:
        _print_diff(output_files, before_inputs, after_inputs, "inputs",
                    before_file, after_file)
        found_difference = True

  if not found_difference:
    print("No difference")


def to_absolute_path(path):
  path = os.path.expanduser(path)
  if os.path.isabs(path):
    return path
  else:
    if "BUILD_WORKING_DIRECTORY" in os.environ:
      return os.path.join(os.environ["BUILD_WORKING_DIRECTORY"], path)
    else:
      return path


def main(unused_argv):
  before_file = to_absolute_path(flags.FLAGS.before)
  after_file = to_absolute_path(flags.FLAGS.after)
  input_type = flags.FLAGS.input_type
  attrs = flags.FLAGS.attrs

  before_proto = analysis_v2_pb2.ActionGraphContainer()
  after_proto = analysis_v2_pb2.ActionGraphContainer()
  if input_type == "proto":
    with open(before_file, "rb") as f:
      before_proto.ParseFromString(f.read())
    with open(after_file, "rb") as f:
      after_proto.ParseFromString(f.read())
  else:
    with open(before_file, "r") as f:
      before_text = f.read()
      text_format.Merge(before_text, before_proto)
    with open(after_file, "r") as f:
      after_text = f.read()
      text_format.Merge(after_text, after_proto)

  _aquery_diff(before_proto, after_proto, attrs, before_file, after_file)


if __name__ == "__main__":
  app.run(main)
