// 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 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/tester/flutter_tester.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';

import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart';

void main() {
  MemoryFileSystem fs;

  setUp(() {
    fs = MemoryFileSystem();
  });

  group('FlutterTesterApp', () {
    testUsingContext('fromCurrentDirectory', () async {
      const String projectPath = '/home/my/projects/my_project';
      await fs.directory(projectPath).create(recursive: true);
      fs.currentDirectory = projectPath;

      final FlutterTesterApp app = FlutterTesterApp.fromCurrentDirectory();
      expect(app.name, 'my_project');
      expect(app.packagesFile.path, fs.path.join(projectPath, '.packages'));
    }, overrides: <Type, Generator>{
      FileSystem: () => fs,
      ProcessManager: () => FakeProcessManager.any(),
    });
  });

  group('FlutterTesterDevices', () {
    tearDown(() {
      FlutterTesterDevices.showFlutterTesterDevice = false;
    });

    testUsingContext('no device', () async {
      final FlutterTesterDevices discoverer = FlutterTesterDevices();

      final List<Device> devices = await discoverer.devices;
      expect(devices, isEmpty);
    });

    testUsingContext('has device', () async {
      FlutterTesterDevices.showFlutterTesterDevice = true;
      final FlutterTesterDevices discoverer = FlutterTesterDevices();

      final List<Device> devices = await discoverer.devices;
      expect(devices, hasLength(1));

      final Device device = devices.single;
      expect(device, isInstanceOf<FlutterTesterDevice>());
      expect(device.id, 'flutter-tester');
    });
  });

  group('FlutterTesterDevice', () {
    FlutterTesterDevice device;
    List<String> logLines;

    setUp(() {
      device = FlutterTesterDevice('flutter-tester');

      logLines = <String>[];
      device.getLogReader().logLines.listen(logLines.add);
    });

    testUsingContext('getters', () async {
      expect(device.id, 'flutter-tester');
      expect(await device.isLocalEmulator, isFalse);
      expect(device.name, 'Flutter test device');
      expect(device.portForwarder, isNot(isNull));
      expect(await device.targetPlatform, TargetPlatform.tester);

      expect(await device.installApp(null), isTrue);
      expect(await device.isAppInstalled(null), isFalse);
      expect(await device.isLatestBuildInstalled(null), isFalse);
      expect(await device.uninstallApp(null), isTrue);

      expect(device.isSupported(), isTrue);
    });

    group('startApp', () {
      String flutterRoot;
      String flutterTesterPath;

      String projectPath;
      String mainPath;

      MockArtifacts mockArtifacts;
      MockProcessManager mockProcessManager;
      MockProcess mockProcess;
      MockBuildSystem mockBuildSystem;

      final Map<Type, Generator> startOverrides = <Type, Generator>{
        Platform: () => FakePlatform(operatingSystem: 'linux'),
        FileSystem: () => fs,
        ProcessManager: () => mockProcessManager,
        Artifacts: () => mockArtifacts,
        BuildSystem: () => mockBuildSystem,
      };

      setUp(() {
        mockBuildSystem = MockBuildSystem();
        flutterRoot = fs.path.join('home', 'me', 'flutter');
        flutterTesterPath = fs.path.join(flutterRoot, 'bin', 'cache',
            'artifacts', 'engine', 'linux-x64', 'flutter_tester');
        final File flutterTesterFile = fs.file(flutterTesterPath);
        flutterTesterFile.parent.createSync(recursive: true);
        flutterTesterFile.writeAsBytesSync(const <int>[]);

        projectPath = fs.path.join('home', 'me', 'hello');
        mainPath = fs.path.join(projectPath, 'lin', 'main.dart');

        mockProcessManager = MockProcessManager();
        mockProcessManager.processFactory =
            (List<String> commands) => mockProcess;

        mockArtifacts = MockArtifacts();
        final String artifactPath = fs.path.join(flutterRoot, 'artifact');
        fs.file(artifactPath).createSync(recursive: true);
        when(mockArtifacts.getArtifactPath(
          any,
          mode: anyNamed('mode')
        )).thenReturn(artifactPath);

        when(mockBuildSystem.build(
          any,
          any,
        )).thenAnswer((_) async {
          fs.file('$mainPath.dill').createSync(recursive: true);
          return BuildResult(success: true);
        });
      });

      testUsingContext('not debug', () async {
        final LaunchResult result = await device.startApp(null,
            mainPath: mainPath,
            debuggingOptions: DebuggingOptions.disabled(const BuildInfo(BuildMode.release, null)));

        expect(result.started, isFalse);
      }, overrides: startOverrides);


      testUsingContext('start', () async {
        final Uri observatoryUri = Uri.parse('http://127.0.0.1:6666/');
        mockProcess = MockProcess(stdout: Stream<List<int>>.fromIterable(<List<int>>[
          '''
Observatory listening on $observatoryUri
Hello!
'''
              .codeUnits,
        ]));

        final LaunchResult result = await device.startApp(null,
            mainPath: mainPath,
            debuggingOptions: DebuggingOptions.enabled(const BuildInfo(BuildMode.debug, null)));
        expect(result.started, isTrue);
        expect(result.observatoryUri, observatoryUri);
        expect(logLines.last, 'Hello!');
      }, overrides: startOverrides);
    });
  });
}

class MockBuildSystem extends Mock implements BuildSystem {}
class MockArtifacts extends Mock implements Artifacts {}
