// Copyright (c) 2017, 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.

/// Shared code used by fasta_perf and incremental_perf.
library front_end.tool.perf_common;

import 'dart:io' show exitCode, stderr;

import 'package:kernel/target/targets.dart' show Target, TargetFlags;

import 'package:vm/target/flutter.dart' show FlutterTarget;

import 'package:vm/target/vm.dart' show VmTarget;

import 'package:front_end/src/api_prototype/front_end.dart'
    show CompilationMessage;

import 'package:front_end/src/fasta/fasta_codes.dart' as fastaCodes;

import 'package:front_end/src/fasta/severity.dart'
    show Severity, severityPrefixes;

/// Error messages that we temporarily allow when compiling benchmarks in strong
/// mode.
///
/// This whitelist lets us run the compiler benchmarks while those errors get
/// fixed. We don't blindly allow any error message because we would then miss
/// situations where the benchmarks are actually broken.
///
/// Note: the performance bots compile both dart2js and the flutter-gallery app
/// as benchmarks, so they both need to be checked before we remove a message
/// from this set.
final whitelistMessageCode = new Set<String>.from(<String>[
  // Code names in this list should match the key used in messages.yaml
  fastaCodes.codeInvalidAssignment.name,
  fastaCodes.codeOverrideTypeMismatchParameter.name,
  fastaCodes.codeOverriddenMethodCause.name,

  // The following errors are not covered by unit tests in the SDK repo because
  // they are only seen today in the flutter-gallery benchmark (external to
  // this repo).
  fastaCodes.codeInvalidCastFunctionExpr.name,
  fastaCodes.codeInvalidCastTopLevelFunction.name,
  fastaCodes.codeUndefinedGetter.name,
  fastaCodes.codeUndefinedMethod.name,
]);

onErrorHandler(bool isStrong) {
  bool messageReported = false;
  return (CompilationMessage m) {
    if (m.severity == Severity.internalProblem ||
        m.severity == Severity.error) {
      if (!isStrong || !whitelistMessageCode.contains(m.code)) {
        var uri = m.span?.start?.sourceUrl ?? "?";
        var offset = m.span?.start?.offset ?? "?";
        stderr.writeln('$uri:$offset: '
            '${severityPrefixes[m.severity]}: ${m.message}');
        exitCode = 1;
      } else if (!messageReported) {
        messageReported = true;
        stderr.writeln('Whitelisted error messages omitted');
      }
    }
  };
}

/// Creates a [VmTarget] or [FlutterTarget] with strong-mode enabled or
/// disabled.
// TODO(sigmund): delete as soon as the disableTypeInference flag and the
// strongMode flag get merged, and we have a single way of specifying the
// strong-mode flag to the FE.
Target createTarget({bool isFlutter: false, bool strongMode: true}) {
  var flags = new TargetFlags(strongMode: strongMode);
  if (isFlutter) {
    return strongMode
        ? new FlutterTarget(flags)
        : new LegacyFlutterTarget(flags);
  } else {
    return strongMode ? new VmTarget(flags) : new LegacyVmTarget(flags);
  }
}

class LegacyVmTarget extends VmTarget {
  LegacyVmTarget(TargetFlags flags) : super(flags);

  @override
  bool get disableTypeInference => true;
}

class LegacyFlutterTarget extends FlutterTarget {
  LegacyFlutterTarget(TargetFlags flags) : super(flags);

  @override
  bool get disableTypeInference => true;
}

class TimingsCollector {
  final Stopwatch stopwatch = new Stopwatch();

  final Map<String, List<double>> timings = <String, List<double>>{};

  final bool verbose;

  TimingsCollector(this.verbose);

  String currentKey;

  void start(String key) {
    if (currentKey != null) {
      throw "Attempt to time '$key' while '$currentKey' is running.";
    }
    currentKey = key;
    stopwatch
      ..reset()
      ..start();
  }

  void stop(String key) {
    stopwatch.stop();
    if (currentKey == null) {
      throw "Need to call 'start' before calling 'stop'.";
    }
    if (currentKey != key) {
      throw "Can't stop timing '$key' because '$currentKey' is running.";
    }
    currentKey = null;
    double duration =
        stopwatch.elapsedMicroseconds / Duration.microsecondsPerMillisecond;
    List<double> durations = (timings[key] ??= <double>[]);
    durations.add(duration);
    if (verbose) {
      print("$key took: ${duration}ms");
    }
  }

  void printTimings() {
    timings.forEach((String key, List<double> durations) {
      double total = 0.0;
      for (double duration in durations.skip(3)) {
        total += duration;
      }
      print("$key took: ${total / (durations.length - 3)}ms");
    });
  }
}
