// 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:developer';
import 'dart:io';

import 'package:observatory_2/service_io.dart';
import 'package:test/test.dart';

import 'test_helper.dart';

primeTimeline() {
  Timeline.startSync('apple');
  Timeline.instantSync('ISYNC', arguments: {'fruit': 'banana'});
  Timeline.finishSync();
  TimelineTask parentTask = TimelineTask.withTaskId(42);
  TimelineTask task = TimelineTask(parent: parentTask, filterKey: 'testFilter');
  task.start('TASK1', arguments: {'task1-start-key': 'task1-start-value'});
  task.instant('ITASK',
      arguments: {'task1-instant-key': 'task1-instant-value'});
  task.finish(arguments: {'task1-finish-key': 'task1-finish-value'});

  Flow flow = Flow.begin(id: 123);
  Timeline.startSync('peach', flow: flow);
  Timeline.finishSync();
  Timeline.startSync('watermelon', flow: Flow.step(flow.id));
  Timeline.finishSync();
  Timeline.startSync('pear', flow: Flow.end(flow.id));
  Timeline.finishSync();
}

List filterForDartEvents(List events) {
  return events.where((event) => event['cat'] == 'Dart').toList();
}

bool mapContains(Map map, Map submap) {
  for (var key in submap.keys) {
    if (map[key] != submap[key]) {
      return false;
    }
  }
  return true;
}

bool eventsContains(List events, String phase, String name, [Map arguments]) {
  for (Map event in events) {
    if ((event['ph'] == phase) && (event['name'] == name)) {
      if (arguments == null) {
        return true;
      } else if (mapContains(event['args'], arguments)) {
        return true;
      }
    }
  }
  return false;
}

int timeOrigin(List events) {
  if (events.length == 0) {
    return 0;
  }
  int smallest = events[0]['ts'];
  for (var i = 0; i < events.length; i++) {
    Map event = events[i];
    if (event['ts'] < smallest) {
      smallest = event['ts'];
    }
  }
  return smallest;
}

int timeDuration(List events, int timeOrigin) {
  if (events.length == 0) {
    return 0;
  }
  int biggestDuration = events[0]['ts'] - timeOrigin;
  for (var i = 0; i < events.length; i++) {
    Map event = events[i];
    int duration = event['ts'] - timeOrigin;
    if (duration > biggestDuration) {
      biggestDuration = duration;
    }
  }
  return biggestDuration;
}

void allEventsHaveIsolateNumber(List events) {
  for (Map event in events) {
    if (event['ph'] == 'M') {
      // Skip meta-data events.
      continue;
    }
    if (event['name'] == 'Runnable' && event['ph'] == 'i') {
      // Skip Runnable events which don't have an isolate.
      continue;
    }
    if (event['cat'] == 'VM') {
      // Skip VM category events which don't have an isolate.
      continue;
    }
    if (event['cat'] == 'API') {
      // Skip API category events which sometimes don't have an isolate.
      continue;
    }
    if (event['cat'] == 'Embedder' &&
        (event['name'] == 'DFE::ReadScript' ||
            event['name'] == 'CreateIsolateGroupAndSetupHelper')) {
      continue;
    }
    Map arguments = event['args'];
    expect(arguments, isA<Map>());
    expect(arguments['isolateGroupId'], isA<String>());
    if (!const ['GC', 'Compiler', 'CompilerVerbose'].contains(event['cat']) &&
        !const ['FinishTopLevelClassLoading', 'FinishClassLoading']
            .contains(event['name'])) {
      expect(arguments['isolateId'], isA<String>());
    }
  }
}

var tests = <VMTest>[
  (VM vm) async {
    Map result = await vm.invokeRpcNoUpgrade('getVMTimeline', {});
    expect(result['type'], equals('Timeline'));
    expect(result['traceEvents'], isA<List>());
    final int numEvents = result['traceEvents'].length;
    List dartEvents = filterForDartEvents(result['traceEvents']);
    expect(dartEvents.length, greaterThanOrEqualTo(11));
    allEventsHaveIsolateNumber(dartEvents);
    allEventsHaveIsolateNumber(result['traceEvents']);
    expect(
        eventsContains(dartEvents, 'i', 'ISYNC', {'fruit': 'banana'}), isTrue);
    expect(eventsContains(dartEvents, 'B', 'apple'), isTrue);
    expect(eventsContains(dartEvents, 'E', 'apple'), isTrue);
    expect(
        eventsContains(dartEvents, 'b', 'TASK1', {
          'filterKey': 'testFilter',
          'task1-start-key': 'task1-start-value',
          'parentId': 42.toRadixString(16)
        }),
        isTrue);
    expect(
        eventsContains(dartEvents, 'e', 'TASK1', {
          'filterKey': 'testFilter',
          'task1-finish-key': 'task1-finish-value',
        }),
        isTrue);
    expect(
        eventsContains(dartEvents, 'n', 'ITASK', {
          'filterKey': 'testFilter',
          'task1-instant-key': 'task1-instant-value',
        }),
        isTrue);
    expect(eventsContains(dartEvents, 'q', 'ITASK'), isFalse);
    expect(eventsContains(dartEvents, 'B', 'peach'), isTrue);
    expect(eventsContains(dartEvents, 'E', 'peach'), isTrue);
    expect(eventsContains(dartEvents, 'B', 'watermelon'), isTrue);
    expect(eventsContains(dartEvents, 'E', 'watermelon'), isTrue);
    expect(eventsContains(dartEvents, 'B', 'pear'), isTrue);
    expect(eventsContains(dartEvents, 'E', 'pear'), isTrue);
    expect(eventsContains(dartEvents, 's', '123'), isTrue);
    expect(eventsContains(dartEvents, 't', '123'), isTrue);
    expect(eventsContains(dartEvents, 'f', '123'), isTrue);
    // Calculate the time Window of Dart events.
    int origin = timeOrigin(dartEvents);
    int extent = timeDuration(dartEvents, origin);
    // Query for the timeline with the time window for Dart events.
    result = await vm.invokeRpcNoUpgrade('getVMTimeline',
        {'timeOriginMicros': origin, 'timeExtentMicros': extent});
    // Verify that we received fewer events than before.
    expect(result['traceEvents'].length, lessThan(numEvents));
    // Verify that we have the same number of Dart events.
    List dartEvents2 = filterForDartEvents(result['traceEvents']);
    expect(dartEvents2.length, dartEvents.length);
  },
];

main(List<String> args) async {
  // Running the subprocesses of this particular test in opt counter mode
  // will cause it to be slow and cause many compilations.
  //
  // Together with "--complete-timeline" this will create a huge number of
  // timeline events which can, on ia32, cause the process to hit OOM.
  //
  // So we filter out that particular argument.
  final executableArgs = Platform.executableArguments
      .where((String arg) => !arg.contains('optimization-counter-threshold'))
      .toList();

  await runVMTests(args, tests,
      testeeBefore: primeTimeline,
      extraArgs: ['--complete-timeline'],
      executableArgs: executableArgs);
}
