# 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/cmd_line_differ:cmd_line_differ -- \
--before=/path/to/output_one.textproto \
--after=/path/to/output_two.textproto
--input_type=textproto
"""

import os
from absl import app
from absl import flags
from google.protobuf import text_format
from src.main.protobuf import analysis_pb2

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.mark_flag_as_required("before")
flags.mark_flag_as_required("after")


def _map_artifact_id_to_path(artifacts):
  return {artifact.id: artifact.exec_path for artifact in artifacts}


def _map_output_files_to_command_line(actions, artifacts):
  output_files_to_command_line = {}
  for action in actions:
    output_files = " ".join(
        sorted([artifacts[output_id] for output_id in action.output_ids]))
    output_files_to_command_line[output_files] = action.arguments
  return output_files_to_command_line


def _aquery_diff(before, after):
  """Returns differences between command lines that generate same outputs."""
  # TODO(bazel-team): Currently we compare only command lines of actions that
  # generate the same output files. Expand the differ to compare other values as
  # well (e.g. mnemonic, inputs, execution tags...).

  found_difference = False
  artifacts_before = _map_artifact_id_to_path(before.artifacts)
  artifacts_after = _map_artifact_id_to_path(after.artifacts)

  output_to_command_line_before = _map_output_files_to_command_line(
      before.actions, artifacts_before)
  output_to_command_line_after = _map_output_files_to_command_line(
      after.actions, artifacts_after)

  output_files_before = set(output_to_command_line_before.keys())
  output_files_after = set(output_to_command_line_after.keys())

  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

  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(("Difference in action that generates the following outputs:\n%s\n"
             "Aquery output before change has the following command line:\n%s\n"
             "Aquery output after change has the following command line:\n%s\n")
            % ("\n".join(output_files.split()), "\n".join(arguments),
               "\n".join(after_arguments)))
      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

  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)


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