// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:args/args.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/postmortem_file.dart';
import 'package:nnbd_migration/src/variables.dart';

main(List<String> args) {
  ArgParser argParser = ArgParser();
  ArgResults parsedArgs;

  argParser.addOption('file',
      abbr: 'f', help: 'The postmortem file to analyze');

  argParser.addFlag('help',
      abbr: 'h', negatable: false, help: 'Print usage info');

  List<Subcommand> subcommands = [
    Subcommand(
        name: 'dot', help: 'Output graph as dot file', argParser: ArgParser()),
    Subcommand(name: 'help', help: 'Print usage info', argParser: ArgParser()),
    Subcommand(
        name: 'steps', help: 'Print propagation steps', argParser: ArgParser()),
    Subcommand(
        name: 'files', help: 'Print input file paths', argParser: ArgParser()),
    Subcommand(
        name: 'decorations',
        suffix: '<path>',
        help: 'Print decorations for a file',
        argParser: ArgParser()),
    Subcommand(
      name: 'node',
      suffix: '<id>',
      help: 'Print details about a node',
      argParser: ArgParser(),
    ),
    Subcommand(
      name: 'trace',
      suffix: '<id>',
      help: 'Print a trace of why a node was made nullable/non-nullable',
      argParser: ArgParser(),
    ),
    Subcommand(
      name: 'trace_lengths',
      help: 'Print the lengths of all traces',
      argParser: ArgParser(),
    ),
  ];

  for (var subcommand in subcommands) {
    argParser.addCommand(subcommand.name, subcommand.argParser);
  }

  try {
    parsedArgs = argParser.parse(args);
  } on ArgParserException {
    stderr.writeln(argParser.usage);
    exit(1);
  }
  var command = parsedArgs.command;
  if (parsedArgs['help'] as bool || command == null || command.name == 'help') {
    print(argParser.usage);
    for (var subcommand in subcommands) {
      print('');
      var suffix = subcommand.suffix == null ? '' : ' ${subcommand.suffix}';
      print('Subcommand ${subcommand.name}$suffix: ${subcommand.help}');
      print(subcommand.argParser.usage);
    }
    exit(0);
  }
  var filePath = parsedArgs['file'] as String;
  if (filePath == null) {
    print('Must specify a file to analyze using -f');
    exit(1);
  }
  var reader = PostmortemFileReader.read(
      PhysicalResourceProvider.INSTANCE.getFile(filePath));
  switch (command.name) {
    case 'dot':
      reader.graph.debugDump();
      break;
    case 'steps':
      for (var step in reader.propagationSteps) {
        print(step.toString(idMapper: reader.idMapper));
      }
      break;
    case 'trace':
      var nodes = command.rest;
      if (nodes.length != 1) {
        print('Must specify exactly one node id after "node"');
        exit(1);
      }
      var id = int.parse(nodes[0]);
      var node = reader.deserializer.nodeForId(id);
      for (var step in reader.propagationSteps) {
        if (step is DownstreamPropagationStep &&
            identical(node, step.targetNode)) {
          print('Trace');
          int i = 0;
          while (step != null) {
            var codeReference = step.codeReference;
            var codeReferencePrefix =
                codeReference == null ? '' : '$codeReference: ';
            print('#${i++}\t$codeReferencePrefix$step');
            step = step.principalCause;
          }
        }
      }
      break;
    case 'trace_lengths':
      for (var step in reader.propagationSteps) {
        if (step is DownstreamPropagationStep) {
          print('trace length ${_traceLength(step)} for node id '
              '${reader.deserializer.idForNode(step.targetNode)}');
        }
      }
      break;
    case 'files':
      for (var entry in reader.fileDecorations.keys) {
        print(entry);
      }
      break;
    case 'decorations':
      var paths = command.rest;
      if (paths.length != 1) {
        print('Must specify exactly one path after "decorations"');
        exit(1);
      }
      var path = paths[0];
      var decorations = reader.fileDecorations[path];
      if (decorations == null) {
        print('Path not found: $path');
        exit(1);
      }
      for (var decorationEntry in decorations.entries) {
        for (var roleEntry in decorationEntry.value.entries) {
          var span = Variables.spanForUniqueIdentifier(decorationEntry.key);
          var nodeId = reader.idMapper.idForNode(roleEntry.value);
          print('${span.offset}-${span.end}${roleEntry.key}: $nodeId');
        }
      }
      break;
    case 'node':
      var nodes = command.rest;
      if (nodes.length != 1) {
        print('Must specify exactly one node id after "node"');
        exit(1);
      }
      var id = int.parse(nodes[0]);
      var node = reader.deserializer.nodeForId(id);
      print('Node $id: $node');
      print('Decorations:');
      reader.findDecorationsByNode(node, (path, span, role) {
        print('  $path:$span$role');
      });
      print('Upstream edges:');
      for (var edge in node.upstreamEdges) {
        var description =
            (edge as NullabilityEdge).toString(idMapper: reader.idMapper);
        print('  $description');
      }
      print('Downstream edges:');
      for (var edge in node.downstreamEdges) {
        var description =
            (edge as NullabilityEdge).toString(idMapper: reader.idMapper);
        print('  $description');
      }
      if (node is NullabilityNodeCompound) {
        var componentsByName = node.componentsByName;
        print('Components:');
        for (var entry in componentsByName.entries) {
          var description = entry.value.toString(idMapper: reader.idMapper);
          print('  ${entry.key}: $description');
        }
      }
      break;
    default:
      throw StateError('Unrecognized command: $command');
  }
}

int _traceLength(PropagationStep step) {
  int traceLength = 0;
  while (step != null) {
    traceLength++;
    step = step.principalCause;
  }
  return traceLength;
}

class Subcommand {
  final String name;
  final String suffix;
  final String help;
  final ArgParser argParser;

  Subcommand(
      {@required this.name,
      this.suffix,
      @required this.help,
      @required this.argParser});
}
