// Copyright 2014 The Flutter Authors. 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:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'dart:isolate' as isolate;

import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  String isolateId;
  final TimelineObtainer timelineObtainer = TimelineObtainer();

  setUpAll(() async {
    isolateId = developer.Service.getIsolateID(isolate.Isolate.current);
    final developer.ServiceProtocolInfo info = await developer.Service.getInfo();

    if (info.serverUri == null) {
      fail('This test _must_ be run with --enable-vmservice.');
    }
    await timelineObtainer.connect(info.serverUri);
    await timelineObtainer.setDartFlags();

    // Initialize the image cache.
    TestWidgetsFlutterBinding.ensureInitialized();
  });

  tearDownAll(() async {
    await timelineObtainer?.close();
  });

  test('Image cache tracing', () async {
    final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
    PaintingBinding.instance.imageCache.putIfAbsent(
      'Test',
      () => completer1,
    );
    PaintingBinding.instance.imageCache.clear();

    final List<Map<String, dynamic>> timelineEvents = await timelineObtainer.getTimelineData();

    _expectTimelineEvents(
      timelineEvents,
      <Map<String, dynamic>>[
        <String, dynamic>{
          'name': 'ImageCache.putIfAbsent',
          'args': <String, dynamic>{'key': 'Test', 'isolateId': isolateId}
        },
        <String, dynamic>{
          'name': 'listener',
          'args': <String, dynamic>{'parentId': '1', 'isolateId': isolateId}
        },
        <String, dynamic>{
          'name': 'ImageCache.clear',
          'args': <String, dynamic>{
            'pendingImages': 1,
            'keepAliveImages': 0,
            'liveImages': 1,
            'currentSizeInBytes': 0,
            'isolateId': isolateId,
          }
        },
      ],
    );
  }, skip: isBrowser); // uses dart:isolate and io
}

void _expectTimelineEvents(
  List<Map<String, dynamic>> events,
  List<Map<String, dynamic>> expected,
) {
  for (final Map<String, dynamic> event in events) {
    for (int index = 0; index < expected.length; index += 1) {
      if (expected[index]['name'] == event['name']) {
        final Map<String, dynamic> expectedArgs = expected[index]['args'] as Map<String, dynamic>;
        final Map<String, dynamic> args = event['args'] as Map<String, dynamic>;
        if (_mapsEqual(expectedArgs, args)) {
          expected.removeAt(index);
        }
      }
    }
  }
  if (expected.isNotEmpty) {
    final String encodedEvents = jsonEncode(events);
    fail('Timeline did not contain expected events: $expected\nactual: $encodedEvents');
  }
}

bool _mapsEqual(Map<String, dynamic> expectedArgs, Map<String, dynamic> args) {
  for (final String key in expectedArgs.keys) {
    if (expectedArgs[key] != args[key]) {
      return false;
    }
  }
  return true;
}

// TODO(dnfield): we can drop this in favor of vm_service when https://github.com/dart-lang/webdev/issues/899 is resolved.
class TimelineObtainer {
  WebSocket _observatorySocket;
  int _lastCallId = 0;

  final Map<int, Completer<dynamic>> _completers = <int, Completer<dynamic>>{};


  Future<void> connect(Uri uri) async {
    _observatorySocket = await WebSocket.connect('ws://localhost:${uri.port}${uri.path}ws');
    _observatorySocket.listen((dynamic data) => _processResponse(data as String));
  }

  void _processResponse(String data) {
    final Map<String, dynamic> json = jsonDecode(data) as Map<String, dynamic>;
    final int id = json['id'] as int;
    _completers.remove(id).complete(json['result']);
  }

  Future<bool> setDartFlags() async {
    _lastCallId += 1;
    final Completer<Map<String, dynamic>> completer = Completer<Map<String, dynamic>>();
    _completers[_lastCallId] = completer;
    _observatorySocket.add(jsonEncode(<String, dynamic>{
      'id': _lastCallId,
      'method': 'setVMTimelineFlags',
      'params': <String, dynamic>{
        'recordedStreams': <String>['Dart'],
      },
    }));

    final Map<String, dynamic> result = await completer.future;
    return result['type'] == 'Success';
  }

  Future<List<Map<String, dynamic>>> getTimelineData() async {
    _lastCallId += 1;
    final Completer<Map<String, dynamic>> completer = Completer<Map<String, dynamic>>();
    _completers[_lastCallId] = completer;
    _observatorySocket.add(jsonEncode(<String, dynamic>{
      'id': _lastCallId,
      'method': 'getVMTimeline',
    }));

    final Map<String, dynamic> result = await completer.future;
    final List<dynamic> list = result['traceEvents'] as List<dynamic>;
    return list.cast<Map<String, dynamic>>();
  }

  Future<void> close() async {
    expect(_completers, isEmpty);
    await _observatorySocket?.close();
  }
}

class TestImageStreamCompleter extends ImageStreamCompleter {}
