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

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

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

const String _kActivityId = 'io.flutter.examples.named_isolates/com.example.view.MainActivity';
const String _kFirstIsolateName = 'first isolate name';
const String _kSecondIsolateName = 'second isolate name';

void main() {
  task(() async {
    final AndroidDevice device = await devices.workingDevice as AndroidDevice;
    await device.unlock();

    section('Compile and run the tester app');
    Completer<void> firstNameFound = Completer<void>();
    Completer<void> secondNameFound = Completer<void>();
    final Process runProcess = await _run(device: device, command:
        <String>['run', '--disable-service-auth-codes'], stdoutListener: (String line) {
      if (line.contains(_kFirstIsolateName)) {
        firstNameFound.complete();
      } else if (line.contains(_kSecondIsolateName)) {
        secondNameFound.complete();
      }
    });

    section('Verify all the debug isolate names are set');
    runProcess.stdin.write('l');
    await Future.wait<dynamic>(<Future<dynamic>>[firstNameFound.future, secondNameFound.future])
                .timeout(const Duration(seconds: 1), onTimeout: () => throw 'Isolate names not found.');
    await _quitRunner(runProcess);

    section('Attach to the second debug isolate');
    firstNameFound = Completer<void>();
    secondNameFound = Completer<void>();
    final String currentTime = (await device.shellEval('date', <String>['"+%F %R:%S.000"'])).trim();
    await device.shellExec('am', <String>['start', '-n', _kActivityId]);
    final String observatoryLine = await device.adb(<String>['logcat', '-e', 'Observatory listening on http:', '-m', '1', '-T', currentTime]);
    print('Found observatory line: $observatoryLine');
    final String observatoryUri = RegExp('Observatory listening on ((http|\/\/)[a-zA-Z0-9:/=_\\-\.\\[\\]]+)').firstMatch(observatoryLine)[1];
    print('Extracted observatory port: $observatoryUri');
    final Process attachProcess =
      await _run(device: device, command: <String>['attach', '--debug-uri',
          observatoryUri, '--isolate-filter', '$_kSecondIsolateName'], stdoutListener: (String line) {
        if (line.contains(_kFirstIsolateName)) {
          firstNameFound.complete();
        } else if (line.contains(_kSecondIsolateName)) {
          secondNameFound.complete();
        }
      });
    attachProcess.stdin.write('l');
    await secondNameFound.future;
    if (firstNameFound.isCompleted)
      throw '--isolate-filter failed to attach to a specific isolate';
    await _quitRunner(attachProcess);

    return TaskResult.success(null);
  });
}

Future<Process> _run({@required Device device, @required List<String> command, @required Function(String) stdoutListener}) async {
  final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/named_isolates'));
  Process runner;
  bool observatoryConnected = false;
  await inDirectory(appDir, () async {
  runner = await startProcess(
      path.join(flutterDirectory.path, 'bin', 'flutter'),
      <String>['--suppress-analytics', '-d', device.deviceId, ...command],
      isBot: false, // we just want to test the output, not have any debugging info
    );
    final StreamController<String> stdout = StreamController<String>.broadcast();

    // Mirror output to stdout, listen for ready message
    final Completer<void> appReady = Completer<void>();
    runner.stdout
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen((String line) {
        print('run:stdout: $line');
        stdout.add(line);
        if (parseServicePort(line) != null) {
          appReady.complete();
          observatoryConnected = true;
        }
        stdoutListener(line);
      });
    runner.stderr
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen((String line) {
        stderr.writeln('run:stderr: $line');
      });

    // Wait for either the process to fail or for the run to begin.
    await Future.any<dynamic>(<Future<dynamic>>[ appReady.future, runner.exitCode ]);
    if (!observatoryConnected)
      throw 'Failed to find service port when running `${command.join(' ')}`';
  });
  return runner;
}

Future<void> _quitRunner(Process runner) async {
  runner.stdin.write('q');
  final int result = await runner.exitCode;
  if (result != 0)
    throw 'Received unexpected exit code $result when quitting process.';
}
