// 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 {
    int vmServicePort;
    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') {
            vmServicePort = Uri.parse(json['params']['wsUri']).port;
            print('service protocol connection available at port $vmServicePort');
          } else if (json['event'] == 'app.started') {
            appId = json['params']['appId'];
            print('application identifier is $appId');
          }
        }
        if (vmServicePort != 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(
        'ws://localhost:$vmServicePort/ws'
      );

      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);
  });
}
