// 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 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/desktop_device.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';

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

/// A trivial subclass of DesktopDevice for testing the shared functionality.
class FakeDesktopDevice extends DesktopDevice {
  FakeDesktopDevice() : super(
      'dummy',
      platformType: PlatformType.linux,
      ephemeral: false,
  );

  /// The [mainPath] last passed to [buildForDevice].
  String lastBuiltMainPath;

  /// The [buildInfo] last passed to [buildForDevice].
  BuildInfo lastBuildInfo;

  @override
  String get name => 'dummy';

  @override
  Future<TargetPlatform> get targetPlatform async => TargetPlatform.tester;

  @override
  bool isSupported() => true;

  @override
  bool isSupportedForProject(FlutterProject flutterProject) => true;

  @override
  Future<void> buildForDevice(
    ApplicationPackage package, {
    String mainPath,
    BuildInfo buildInfo,
  }) async {
    lastBuiltMainPath = mainPath;
    lastBuildInfo = buildInfo;
  }

  // Dummy implementation that just returns the build mode name.
  @override
  String executablePathForDevice(ApplicationPackage package, BuildMode buildMode) {
    return buildMode == null ? 'null' : getNameForBuildMode(buildMode);
  }
}

/// A desktop device that returns a null executable path, for failure testing.
class NullExecutableDesktopDevice extends FakeDesktopDevice {
  @override
  String executablePathForDevice(ApplicationPackage package, BuildMode buildMode) {
    return null;
  }
}

class MockAppplicationPackage extends Mock implements ApplicationPackage {}

class MockFileSystem extends Mock implements FileSystem {}

class MockFile extends Mock implements File {}

class MockProcessManager extends Mock implements ProcessManager {}

void main() {
  group('Basic info', () {
    test('Category is desktop', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      expect(device.category, Category.desktop);
    });

    test('Not an emulator', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      expect(await device.isLocalEmulator, false);
      expect(await device.emulatorId, null);
    });

    testUsingContext('Uses OS name as SDK name', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      expect(await device.sdkNameAndVersion, os.name);
    });
  });

  group('Install', () {
    test('Install checks always return true', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      expect(await device.isAppInstalled(null), true);
      expect(await device.isLatestBuildInstalled(null), true);
      expect(device.category, Category.desktop);
    });

    test('Install and uninstall are no-ops that report success', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      final MockAppplicationPackage package = MockAppplicationPackage();
      expect(await device.uninstallApp(package), true);
      expect(await device.isAppInstalled(package), true);
      expect(await device.isLatestBuildInstalled(package), true);

      expect(await device.installApp(package), true);
      expect(await device.isAppInstalled(package), true);
      expect(await device.isLatestBuildInstalled(package), true);
      expect(device.category, Category.desktop);
    });
  });

  group('Starting and stopping application', () {
    final MockFileSystem mockFileSystem = MockFileSystem();
    final MockProcessManager mockProcessManager = MockProcessManager();

    // Configures mock environment so that startApp will be able to find and
    // run an FakeDesktopDevice exectuable with for the given mode.
    void setUpMockExecutable(FakeDesktopDevice device, BuildMode mode, {Future<int> exitFuture}) {
      final String executableName = device.executablePathForDevice(null, mode);
      final MockFile mockFile = MockFile();
      when(mockFileSystem.file(executableName)).thenReturn(mockFile);
      when(mockFile.existsSync()).thenReturn(true);
      when(mockProcessManager.start(<String>[executableName])).thenAnswer((Invocation invocation) async {
        return FakeProcess(
          exitCode: Completer<int>().future,
          stdout: Stream<List<int>>.fromIterable(<List<int>>[
            utf8.encode('Observatory listening on http://127.0.0.1/0\n'),
          ]),
          stderr: const Stream<List<int>>.empty(),
        );
      });
      when(mockProcessManager.run(any)).thenAnswer((Invocation invocation) async {
        return ProcessResult(0, 1, '', '');
      });
    }

    test('Stop without start is a successful no-op', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
    final MockAppplicationPackage package = MockAppplicationPackage();
      expect(await device.stopApp(package), true);
    });

    testUsingContext('Can run from prebuilt application', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      final MockAppplicationPackage package = MockAppplicationPackage();
      setUpMockExecutable(device, null);
      final LaunchResult result = await device.startApp(package, prebuiltApplication: true);
      expect(result.started, true);
      expect(result.observatoryUri, Uri.parse('http://127.0.0.1/0'));
    }, overrides: <Type, Generator>{
      FileSystem: () => mockFileSystem,
      ProcessManager: () => mockProcessManager,
    });

    testUsingContext('Null executable path fails gracefully', () async {
      final NullExecutableDesktopDevice device = NullExecutableDesktopDevice();
      final MockAppplicationPackage package = MockAppplicationPackage();
      final LaunchResult result = await device.startApp(package, prebuiltApplication: true);
      expect(result.started, false);
      expect(testLogger.errorText, contains('Unable to find executable to run'));
    });

    testUsingContext('stopApp kills process started by startApp', () async {
      final FakeDesktopDevice device = FakeDesktopDevice();
      final MockAppplicationPackage package = MockAppplicationPackage();
      setUpMockExecutable(device, null);
      final LaunchResult result = await device.startApp(package, prebuiltApplication: true);
      expect(result.started, true);
      expect(await device.stopApp(package), true);
    }, overrides: <Type, Generator>{
      FileSystem: () => mockFileSystem,
      ProcessManager: () => mockProcessManager,
    });
  });

  test('Port forwarder is a no-op', () async {
    final FakeDesktopDevice device = FakeDesktopDevice();
    final DevicePortForwarder portForwarder = device.portForwarder;
    final int result = await portForwarder.forward(2);
    expect(result, 2);
    expect(portForwarder.forwardedPorts.isEmpty, true);
  });
}
