// Copyright (c) 2018 The Chromium 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:io';

import 'package:path/path.dart' as path;
import 'package:vm_service_client/vm_service_client.dart';

import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/utils.dart';

void main() {
  Map<String, dynamic> parseFlutterResponse(String line) {
    if (line.startsWith('[') && line.endsWith(']')) {
      try {
        return json.decode(line)[0];
      } catch (e) {
        // Not valid JSON, so likely some other output that was surrounded by [brackets]
        return null;
      }
    }
    return null;
  }

  Stream<String> transformToLines(Stream<List<int>> byteStream) {
    return byteStream.transform<String>(utf8.decoder).transform<String>(const LineSplitter());
  }

  task(() async {
    Uri vmServiceUri;
    String appId;

    final Device device = await devices.workingDevice;
    await device.unlock();
    final Directory appDir =
        dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
    await inDirectory(appDir, () async {
      final Completer<void> ready = Completer<void>();
      bool ok;
      print('run: starting...');
      final Process run = await startProcess(
        path.join(flutterDirectory.path, 'bin', 'flutter'),
        <String>[
          'run',
          '--machine',
          '--verbose',
          '-d',
          device.deviceId,
          'lib/commands.dart',
        ],
      );
      final StreamController<String> stdout = StreamController<String>.broadcast();
      transformToLines(run.stdout).listen((String line) {
        print('run:stdout: $line');
        stdout.add(line);
        final dynamic json = parseFlutterResponse(line);
        if (json != null) {
          if (json['event'] == 'app.debugPort') {
            vmServiceUri = Uri.parse(json['params']['wsUri']);
            print('service protocol connection available at $vmServiceUri');
          } else if (json['event'] == 'app.started') {
            appId = json['params']['appId'];
            print('application identifier is $appId');
          }
        }
        if (vmServiceUri != null && appId != null && !ready.isCompleted) {
          print('run: ready!');
          ready.complete();
          ok ??= true;
        }
      });
      transformToLines(run.stderr).listen((String line) {
        stderr.writeln('run:stderr: $line');
        ok = false;
      });
      run.exitCode.then<void>((int exitCode) {
        ok = false;
      });
      await Future.any<dynamic>(<Future<dynamic>>[ready.future, run.exitCode]);
      if (!ok)
        throw 'Failed to run test app.';

      final VMServiceClient client = VMServiceClient.connect(vmServiceUri);

      int id = 1;
      Future<Map<String, dynamic>> sendRequest(String method, dynamic params) async {
        final int requestId = id++;
        final Completer<Map<String, dynamic>> response = Completer<Map<String, dynamic>>();
        final StreamSubscription<String> responseSubscription = stdout.stream.listen((String line) {
          final Map<String, dynamic> json = parseFlutterResponse(line);
          if (json != null && json['id'] == requestId)
            response.complete(json);
        });
        final Map<String, dynamic> req = <String, dynamic>{
          'id': requestId,
          'method': method,
          'params': params,
        };
        final String jsonEncoded = json.encode(<Map<String, dynamic>>[req]);
        print('run:stdin: $jsonEncoded');
        run.stdin.writeln(jsonEncoded);
        final Map<String, dynamic> result = await response.future;
        responseSubscription.cancel();
        return result;
      }

      print('test: sending two hot reloads...');
      final Future<dynamic> hotReload1 = sendRequest(
        'app.restart',
        <String, dynamic>{'appId': appId, 'fullRestart': false},
      );
      final Future<dynamic> hotReload2 = sendRequest(
        'app.restart',
        <String, dynamic>{'appId': appId, 'fullRestart': false},
      );
      final Future<List<dynamic>> reloadRequests = Future.wait<dynamic>(<Future<dynamic>>[
        hotReload1,
        hotReload2,
      ]);
      final dynamic results = await Future.any<dynamic>(<Future<dynamic>>[
        run.exitCode,
        reloadRequests,
      ]);

      if (!ok)
        throw 'App failed or crashed during hot reloads.';

      final List<dynamic> responses = results;
      final List<dynamic> errorResponses = responses.where(
        (dynamic r) => r['error'] != null
      ).toList();
      final List<dynamic> successResponses = responses.where(
        (dynamic r) => r['error'] == null &&
                       r['result'] != null &&
                       r['result']['code'] == 0
      ).toList();

      if (errorResponses.length != 1)
        throw 'Did not receive the expected (exactly one) hot reload error response.';
      final String errorMessage = errorResponses.first['error'];
      if (!errorMessage.contains('in progress'))
        throw 'Error response was not that hot reload was in progress.';
      if (successResponses.length != 1)
        throw 'Did not receive the expected (exactly one) successful hot reload response.';

      final dynamic hotReload3 = await sendRequest(
        'app.restart',
        <String, dynamic>{'appId': appId, 'fullRestart': false},
      );
      if (hotReload3['error'] != null)
        throw 'Received an error response from a hot reload after all other hot reloads had completed.';

      sendRequest('app.stop', <String, dynamic>{'appId': appId});
      final int result = await run.exitCode;
      if (result != 0)
        throw 'Received unexpected exit code $result from run process.';
      print('test: validating that the app has in fact closed...');
      await client.done;
    });
    return TaskResult.success(null);
  });
}
