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

Future<String> runFlutterAndQuit(List<String> args, Device device) async {
  final Completer<void> ready = Completer<void>();
  print('run: starting...');
  final Process run = await startProcess(
    path.join(flutterDirectory.path, 'bin', 'flutter'),
    <String>['run', '--suppress-analytics', ...args],
    isBot: false, // we just want to test the output, not have any debugging info
  );
  final List<String> stdout = <String>[];
  final List<String> stderr = <String>[];
  int runExitCode;
  run.stdout.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).listen(
    (String line) {
      print('run:stdout: $line');
      stdout.add(line);
      if (line.contains('>>> FINISHED <<<')) {
        ready.complete();
      }
    },
  );
  run.stderr.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).listen(
    (String line) {
      print('run:stderr: $line');
      stderr.add(line);
    },
  );
  run.exitCode.then<void>((int exitCode) {
    runExitCode = exitCode;
  });
  await Future.any<dynamic>(<Future<dynamic>>[ready.future, run.exitCode]);
  if (runExitCode != null) {
    throw 'Failed to run test app; runner unexpected exited, with exit code $runExitCode.';
  }
  run.stdin.write('q');
  await run.exitCode;
  if (stderr.isNotEmpty) {
    throw 'flutter run ${args.join(' ')} had output on standard error:\n${stderr.join('\n')}';
  }
  return stdout.join('\n');
}

void main() {
  task(() async {
    final Device device = await devices.workingDevice;
    await device.unlock();
    final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
    Future<void> checkMode(String mode, {bool releaseExpected = false, bool dynamic = false}) async {
      await inDirectory(appDir, () async {
        print('run: starting $mode test...');
        final List<String> args = <String>[
          '--$mode',
          if (dynamic) '--dynamic',
          '-d',
          device.deviceId,
          'lib/build_mode.dart',
        ];
        final String stdout = await runFlutterAndQuit(args, device);
        if (!stdout.contains('>>> Release: $releaseExpected <<<')) {
          throw "flutter run --$mode ${dynamic ? '--dynamic ' : ''}didn't set kReleaseMode properly";
        }
      });
    }
    await checkMode('debug', releaseExpected: false);
    await checkMode('profile', releaseExpected: false);
    await checkMode('profile', releaseExpected: false, dynamic: true);
    await checkMode('release', releaseExpected: true);
    await checkMode('release', releaseExpected: true, dynamic: true);
    return TaskResult.success(null);
  });
}
