// Copyright (c) 2017 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() {
  task(() async {
    int vmServicePort;

    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', '--verbose', '--disable-service-auth-codes', '-d', device.deviceId, 'lib/commands.dart'],
      );
      final StreamController<String> stdout = StreamController<String>.broadcast();
      run.stdout
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .listen((String line) {
          print('run:stdout: $line');
          stdout.add(line);
          if (vmServicePort == null) {
            vmServicePort = parseServicePort(line);
            if (vmServicePort != null) {
              print('service protocol connection available at port $vmServicePort');
              print('run: ready!');
              ready.complete();
              ok ??= true;
            }
          }
        });
      run.stderr
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .listen((String line) {
          stderr.writeln('run:stderr: $line');
        });
      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');

      final DriveHelper driver = DriveHelper(vmServicePort);

      await driver.drive('none');
      print('test: pressing "p" to enable debugPaintSize...');
      run.stdin.write('p');
      await driver.drive('debug_paint');
      print('test: pressing "p" again...');
      run.stdin.write('p');
      await driver.drive('none');
      print('test: pressing "P" to enable performance overlay...');
      run.stdin.write('P');
      await driver.drive('performance_overlay');
      print('test: pressing "P" again...');
      run.stdin.write('P');
      await driver.drive('none');
      final Future<String> reloadStartingText =
        stdout.stream.firstWhere((String line) => line.endsWith('] Initializing hot reload...'));
      final Future<String> reloadEndingText =
        stdout.stream.firstWhere((String line) => line.contains('] Reloaded ') && line.endsWith('ms.'));
      print('test: pressing "r" to perform a hot reload...');
      run.stdin.write('r');
      await reloadStartingText;
      await reloadEndingText;
      await driver.drive('none');
      final Future<String> restartStartingText =
        stdout.stream.firstWhere((String line) => line.endsWith('Performing hot restart...'));
      final Future<String> restartEndingText =
        stdout.stream.firstWhere((String line) => line.contains('] Restarted application in '));
      print('test: pressing "R" to perform a full reload...');
      run.stdin.write('R');
      await restartStartingText;
      await restartEndingText;
      await driver.drive('none');
      run.stdin.write('q');
      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.timeout(const Duration(seconds: 5));
    });
    return TaskResult.success(null);
  });
}

class DriveHelper {
  DriveHelper(this.vmServicePort);

  final int vmServicePort;

  Future<void> drive(String name) async {
    print('drive: running commands_$name check...');
    final Process drive = await startProcess(
      path.join(flutterDirectory.path, 'bin', 'flutter'),
      <String>['drive', '--use-existing-app', 'http://127.0.0.1:$vmServicePort/', '--keep-app-running', '--driver', 'test_driver/commands_${name}_test.dart'],
    );
    drive.stdout
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .listen((String line) {
      print('drive:stdout: $line');
    });
    drive.stderr
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .listen((String line) {
      stderr.writeln('drive:stderr: $line');
    });
    final int result = await drive.exitCode;
    if (result != 0)
      throw 'Failed to drive test app (exit code $result).';
    print('drive: finished commands_$name check successfully.');
  }
}
