# Copyright 2018 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 script compares the proto 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:
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

From a bazel repo:
bazel run //tools/aquery_differ:aquery_differ -- \
--before=/path/to/output_one.textproto \
--after=/path/to/output_two.textproto \
--input_type=textproto \
--attrs=cmdline \
--attrs=inputs
"""

from __future__ import print_function
import difflib
import os
import sys
from absl import app
from absl import flags
from google.protobuf import text_format
from src.main.protobuf import analysis_pb2
from tools.aquery_differ.resolvers.dep_set_resolver import DepSetResolver

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):
  return {artifact.id: artifact.exec_path 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)
  artifacts_after = _map_artifact_id_to_path(after_proto.artifacts)

  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_pb2.ActionGraphContainer()
  after_proto = analysis_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)
