#!/usr/bin/env python3
# Copyright 2021 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Command-line tool for finding differences in dependency graphs."""

import argparse

import itertools
from typing import List, Set, Tuple

import chrome_names
import count_cycles
import graph
import serialization


def _print_diff_num_nodes(graph1: graph.Graph, graph2: graph.Graph,
                          label: str):
    before: int = graph1.num_nodes
    after: int = graph2.num_nodes
    _print_diff_metric(before, after, label)


def _print_diff_num_edges(graph1: graph.Graph, graph2: graph.Graph,
                          label: str):
    before: int = graph1.num_edges
    after: int = graph2.num_edges
    _print_diff_metric(before, after, label)


def _print_diff_metric(before: int, after: int, label: str):
    diff: int = after - before
    print(f'{label}: {diff:+} ({before} -> {after})')


def _print_diff_node_list(graph1: graph.Graph, graph2: graph.Graph,
                          label: str):
    before_nodes: Set[str] = set(node.name for node in graph1.nodes)
    after_nodes: Set[str] = set(node.name for node in graph2.nodes)
    _print_set_diff(before_nodes, after_nodes, label)


def _print_diff_edge_list(graph1: graph.Graph, graph2: graph.Graph,
                          label: str):
    before_edges: Set[str] = set(_edge_str(edge) for edge in graph1.edges)
    after_edges: Set[str] = set(_edge_str(edge) for edge in graph2.edges)
    _print_set_diff(before_edges, after_edges, label)


def _edge_str(edge: Tuple[graph.Node, graph.Node]) -> str:
    return f'{edge[0]} -> {edge[1]}'


def _print_diff_cycle_list(cycles1: Set[count_cycles.Cycle],
                           cycles2: Set[count_cycles.Cycle], label: str):
    before_cycles: Set[str] = set(_cycle_str(cycle) for cycle in cycles1)
    after_cycles: Set[str] = set(_cycle_str(cycle) for cycle in cycles2)
    _print_set_diff(before_cycles, after_cycles, label)


def _cycle_str(cycle: count_cycles.Cycle) -> str:
    return ' > '.join(chrome_names.shorten_class(node.name) for node in cycle)


def _print_set_diff(before_set: Set[str], after_set: Set[str], label: str):
    all_added: List[str] = sorted(after_set - before_set)
    all_removed: List[str] = sorted(before_set - after_set)
    if not all_added and not all_removed:
        print(f'{label} - no changes')
        return

    print(f'{label} added (+) and removed (-):')
    for i, added in enumerate(all_added, start=1):
        print(f'+ [{i:4}] {added}')
    for i, removed in enumerate(all_removed, start=1):
        print(f'- [{i:4}] {removed}')


def _cycle_set(graph: graph.Graph,
               max_cycle_size: int) -> Set[count_cycles.Cycle]:
    all_cycles_by_size = count_cycles.find_cycles(graph, max_cycle_size)
    return set(itertools.chain(*all_cycles_by_size))


def main():
    arg_parser = argparse.ArgumentParser(
        description='Given two JSON dependency graphs, output the differences '
        'between them. By default, outputs the differences in the sets of '
        'class and package nodes.')
    required_arg_group = arg_parser.add_argument_group('required arguments')
    required_arg_group.add_argument(
        '-b',
        '--before',
        required=True,
        help='Path to the JSON file containing the "before" dependency graph. '
        'See the README on how to generate this file.')
    required_arg_group.add_argument(
        '-a',
        '--after',
        required=True,
        help='Path to the JSON file containing the "after" dependency graph.')
    arg_parser.add_argument('-e',
                            '--edges',
                            action='store_true',
                            help='Also diff the set of graph edges.')
    arg_parser.add_argument(
        '--package-cycles',
        type=int,
        help='Also diff the set of package cycles up to the specified size.')
    arguments = arg_parser.parse_args()

    class_graph_before, package_graph_before, _ = \
        serialization.load_class_and_package_graphs_from_file(arguments.before)
    class_graph_after, package_graph_after, _ = \
        serialization.load_class_and_package_graphs_from_file(arguments.after)
    _print_diff_num_nodes(class_graph_before, class_graph_after,
                          'Total Java class count')
    _print_diff_num_nodes(package_graph_before, package_graph_after,
                          'Total Java package count')

    print()
    _print_diff_node_list(class_graph_before, class_graph_after,
                          'Java classes')
    print()
    _print_diff_node_list(package_graph_before, package_graph_after,
                          'Java packages')

    if arguments.edges:
        print()
        _print_diff_num_edges(class_graph_before, class_graph_after,
                              'Total Java class edge count')
        _print_diff_num_edges(package_graph_before, package_graph_after,
                              'Total Java package edge count')

        print()
        _print_diff_edge_list(class_graph_before, class_graph_after,
                              'Java class edges')
        print()
        _print_diff_edge_list(package_graph_before, package_graph_after,
                              'Java package edges')

    if arguments.package_cycles:
        cycles_before = _cycle_set(package_graph_before,
                                   arguments.package_cycles)
        cycles_after = _cycle_set(package_graph_after,
                                  arguments.package_cycles)
        print()
        _print_diff_metric(
            len(cycles_before), len(cycles_after),
            'Total Java package cycle count (up to size '
            f'{arguments.package_cycles})')

        print()
        _print_diff_cycle_list(
            cycles_before, cycles_after,
            f'Java package cycles (up to size {arguments.package_cycles})')


if __name__ == '__main__':
    main()
