// Copyright (c) 2022, 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:async';
import 'dart:io';

import 'package:perf_witness/recorder.dart';
import 'package:yaml/yaml.dart';

import '../core.dart';
import '../processes.dart';
import '../utils.dart';

/// Print output useful for diagnosing local issues.
class InfoCommand extends DartdevCommand {
  static const String cmdName = 'info';

  static const String cmdDescription = _DumpCommand.cmdDescription;

  @override
  CommandCategory get commandCategory => CommandCategory.tools;

  InfoCommand({bool verbose = false})
    : super(cmdName, cmdDescription, verbose) {
    addSubcommand(_DumpCommand(verbose: verbose), isDefault: true);
    addSubcommand(_RecordPerformanceCommand(verbose: verbose));
  }
}

class _DumpCommand extends DartdevCommand {
  static const String cmdName = 'dump';

  static const String cmdDescription =
      'Show diagnostic information about the installed tooling.';

  @override
  CommandCategory get commandCategory => CommandCategory.tools;

  _DumpCommand({bool verbose = false})
    : super(cmdName, cmdDescription, verbose) {
    argParser.addFlag(
      removeFilePathsFlag,
      help: 'Remove file paths in displayed information.',
      defaultsTo: true,
    );
  }

  static const String _message =
      'If providing this information as part of reporting a bug, please review '
      "the information\nbelow to ensure it only contains things you're "
      'comfortable posting publicly.';

  static const String removeFilePathsFlag = 'remove-file-paths';

  @override
  FutureOr<int> run() async {
    final elideFilePaths = argResults!.flag(removeFilePathsFlag);

    print('');
    print(_message);

    print('');
    print('#### General info');
    print('');
    print('- Dart ${Platform.version}');
    print(
      '- on ${Platform.operatingSystem} / '
      '${Platform.operatingSystemVersion}',
    );
    print('- locale is ${Platform.localeName}');

    // project information
    var projectInfo = getProjectInfo(project, onlySimpleDeps: elideFilePaths);
    if (projectInfo != null) {
      print('');
      print('#### Project info');
      print('');
      print("- sdk constraint: '${projectInfo.sdkDependency ?? ''}'");
      print('- dependencies: ${projectInfo.dependencies.join(', ')}');
      print('- dev_dependencies: ${projectInfo.devDependencies.join(', ')}');
      if (projectInfo.elidedDependencies > 0) {
        print('- elided dependencies: ${projectInfo.elidedDependencies}');
      }
    }

    // process information
    var processInfo = ProcessInfo.getProcessInfo(
      elideFilePaths: elideFilePaths,
    );
    if (processInfo != null) {
      print('');
      print('#### Process info');
      print('');

      if (processInfo.isEmpty) {
        print('No Dart processes found.');
      } else {
        var table = MarkdownTable();
        table.startRow()
          ..cell('Memory', right: true)
          ..cell('CPU', right: true)
          ..cell('Elapsed time', right: true)
          ..cell('Command line');

        for (var process in processInfo) {
          var row = table.startRow();
          row.cell('${process.memoryMb} MB', right: true);
          row.cell(
            process.cpuPercent == null
                ? '--'
                : '${process.cpuPercent!.toStringAsFixed(1)}%',
            right: true,
          );
          row.cell(process.elapsedTime ?? '', right: true);
          row.cell(process.commandLine);
        }

        print(table.finish().trimRight());
      }
    }

    return 0;
  }
}

class _RecordPerformanceCommand extends DartdevCommand {
  static const String cmdName = 'record-performance';

  static const String cmdDescription =
      'Record performance data of running Dart tooling processes.';

  @override
  CommandCategory get commandCategory => CommandCategory.tools;

  _RecordPerformanceCommand({bool verbose = false})
    : super(cmdName, cmdDescription, verbose) {
    PerfWitnessRecorderConfig.configureArgParser(argParser);
  }

  @override
  FutureOr<int> run() async {
    await record(PerfWitnessRecorderConfig.fromParsedArgs(argResults!));
    return 0;
  }
}

ProjectInfo? getProjectInfo(Project project, {bool onlySimpleDeps = true}) {
  if (!project.hasPubspecFile) {
    return null;
  }

  var pubspec = loadYaml(project.pubspecFile.readAsStringSync()) as Map;
  var elidedDependencies = 0;

  List<String> getDeps(String dependencyType) {
    var deps = pubspec[dependencyType] as Map?;
    var results = <String>[];
    if (deps != null) {
      for (var pkgName in deps.keys) {
        var dep = deps[pkgName];

        // Don't report path: or git: dependencies.
        if (onlySimpleDeps && dep is Map) {
          if (dep.length != 1) {
            elidedDependencies++;
            continue;
          }

          final key = dep.keys.first;
          if (key != 'sdk') {
            elidedDependencies++;
            continue;
          }
        }

        results.add(pkgName);
      }
    }
    return results..sort();
  }

  return ProjectInfo(
    sdkDependency: (pubspec['environment'] as Map?)?['sdk'] as String?,
    dependencies: getDeps('dependencies'),
    devDependencies: getDeps('dev_dependencies'),
    elidedDependencies: elidedDependencies,
  );
}

class ProjectInfo {
  final String? sdkDependency;
  final List<String> dependencies;
  final List<String> devDependencies;
  final int elidedDependencies;

  ProjectInfo({
    required this.sdkDependency,
    required this.dependencies,
    required this.devDependencies,
    required this.elidedDependencies,
  });
}
