// Copyright (c) 2015, 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:convert' show JsonEncoder;
import 'dart:io' show Platform;

import 'package:analyzer/src/generated/utilities_general.dart'
    show PerformanceTag;
import 'package:analyzer/src/task/api/model.dart' show AnalysisTask;
import 'package:analyzer_cli/src/error_formatter.dart';
import 'package:analyzer_cli/src/options.dart' show CommandLineOptions;

const _JSON = const JsonEncoder.withIndent("  ");

final String _osType = () {
  if (Platform.isLinux) {
    return "linux";
  } else if (Platform.isMacOS) {
    return "mac";
  } else if (Platform.isWindows) {
    return "windows";
  } else if (Platform.isAndroid) {
    return "android";
  } else {
    return "unknown";
  }
}();

String makePerfReport(int startTime, int endTime, CommandLineOptions options,
    int analyzedFileCount, AnalysisStats stats) {
  int totalTime = endTime - startTime;
  int otherTime = totalTime;

  var platformJson = <String, dynamic>{
    'osType': _osType,
    'dartSdkVersion': Platform.version,
  };

  var optionsJson = <String, dynamic>{
    'dartSdkPath': options.dartSdkPath,
    'strongMode': options.strongMode,
    'showPackageWarnings': options.showPackageWarnings,
    'showPackageWarningsPrefix': options.showPackageWarningsPrefix,
    'showSdkWarnings': options.showSdkWarnings,
    'definedVariables': options.definedVariables,
    'packageRootPath': options.packageRootPath,
    'packageConfigPath': options.packageConfigPath,
    'sourceFiles': options.sourceFiles,
  };

  // Convert performance tags to JSON representation.
  var perfTagsJson = <String, dynamic>{};
  for (PerformanceTag tag in PerformanceTag.all) {
    if (tag != PerformanceTag.unknown) {
      int tagTime = tag.elapsedMs;
      perfTagsJson[tag.label] = tagTime;
      otherTime -= tagTime;
    }
  }
  perfTagsJson['other'] = otherTime;

  // Generate task table.
  var taskRows = <_TaskRow>[];
  int totalTaskTime = 0;
  for (var key in AnalysisTask.stopwatchMap.keys) {
    var time = AnalysisTask.stopwatchMap[key].elapsedMilliseconds;
    if (time == 0) continue;
    totalTaskTime += time;
    var count = AnalysisTask.countMap[key];
    taskRows.add(new _TaskRow(key.toString(), time, count));
  }
  taskRows.sort((a, b) => b.time.compareTo(a.time));

  var reportJson = <String, dynamic>{
    'perfReportVersion': 0,
    'platform': platformJson,
    'options': optionsJson,
    'totalElapsedTime': totalTime,
    'totalTaskTime': totalTaskTime,
    'analyzedFiles': analyzedFileCount,
    'generatedDiagnostics': stats.unfilteredCount,
    'reportedDiagnostics': stats.filteredCount,
    'performanceTags': perfTagsJson,
    'tasks': taskRows.map((r) => r.toJson()).toList(),
  };

  return _JSON.convert(reportJson);
}

class _TaskRow {
  final String name;
  final int time;
  final int count;
  _TaskRow(this.name, this.time, this.count);

  Map toJson() => <String, dynamic>{'name': name, 'time': time, 'count': count};
}
