// 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:flutter_tools/src/android/android_emulator.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:test/fake.dart';

import '../../src/common.dart';
import '../../src/fake_process_manager.dart';

const String emulatorID = 'i1234';
const String errorText = '[Android emulator test error]';
const List<String> kEmulatorLaunchCommand = <String>[
  'emulator', '-avd', emulatorID,
];

void main() {
  group('android_emulator', () {
    testWithoutContext('flags emulators without config', () {
      const String emulatorID = '1234';

      final AndroidEmulator emulator = AndroidEmulator(
        emulatorID,
        logger: BufferLogger.test(),
        processManager: FakeProcessManager.any(),
        androidSdk: FakeAndroidSdk(),
      );
      expect(emulator.id, emulatorID);
      expect(emulator.hasConfig, false);
    });

    testWithoutContext('flags emulators with config', () {
      const String emulatorID = '1234';
      final AndroidEmulator emulator = AndroidEmulator(
        emulatorID,
        properties: const <String, String>{'name': 'test'},
        logger: BufferLogger.test(),
        processManager: FakeProcessManager.any(),
        androidSdk: FakeAndroidSdk(),
      );

      expect(emulator.id, emulatorID);
      expect(emulator.hasConfig, true);
    });

    testWithoutContext('reads expected metadata', () {
      const String emulatorID = '1234';
      const String manufacturer = 'Me';
      const String displayName = 'The best one';
      final Map<String, String> properties = <String, String>{
        'hw.device.manufacturer': manufacturer,
        'avd.ini.displayname': displayName,
      };
      final AndroidEmulator emulator = AndroidEmulator(
        emulatorID,
        properties: properties,
        logger: BufferLogger.test(),
        processManager: FakeProcessManager.any(),
        androidSdk: FakeAndroidSdk(),
      );

      expect(emulator.id, emulatorID);
      expect(emulator.name, displayName);
      expect(emulator.manufacturer, manufacturer);
      expect(emulator.category, Category.mobile);
      expect(emulator.platformType, PlatformType.android);
    });

    testWithoutContext('prefers displayname for name', () {
      const String emulatorID = '1234';
      const String displayName = 'The best one';
      final Map<String, String> properties = <String, String>{
        'avd.ini.displayname': displayName,
      };
      final AndroidEmulator emulator = AndroidEmulator(
        emulatorID,
        properties: properties,
        logger: BufferLogger.test(),
        processManager: FakeProcessManager.any(),
        androidSdk: FakeAndroidSdk(),
      );

      expect(emulator.name, displayName);
    });

    testWithoutContext('uses cleaned up ID if no displayname is set', () {
      // Android Studio uses the ID with underscores replaced with spaces
      // for the name if displayname is not set so we do the same.
      const String emulatorID = 'This_is_my_ID';
      final Map<String, String> properties = <String, String>{
        'avd.ini.notadisplayname': 'this is not a display name',
      };
      final AndroidEmulator emulator = AndroidEmulator(
        emulatorID,
        properties: properties,
        logger: BufferLogger.test(),
        processManager: FakeProcessManager.any(),
        androidSdk: FakeAndroidSdk(),
      );

      expect(emulator.name, 'This is my ID');
    });

    testWithoutContext('parses ini files', () {
      const String iniFile = '''
        hw.device.name=My Test Name
        #hw.device.name=Bad Name

        hw.device.manufacturer=Me
        avd.ini.displayname = dispName
      ''';
      final Map<String, String> results = parseIniLines(iniFile.split('\n'));

      expect(results['hw.device.name'], 'My Test Name');
      expect(results['hw.device.manufacturer'], 'Me');
      expect(results['avd.ini.displayname'], 'dispName');
    });
  });

  group('Android emulator launch ', () {
    late FakeAndroidSdk mockSdk;

    setUp(() {
      mockSdk = FakeAndroidSdk();
      mockSdk.emulatorPath = 'emulator';
    });

    testWithoutContext('succeeds', () async {
      final AndroidEmulator emulator = AndroidEmulator(emulatorID,
        processManager: FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(command: kEmulatorLaunchCommand),
        ]),
        androidSdk: mockSdk,
        logger: BufferLogger.test(),
      );

      await emulator.launch(startupDuration: Duration.zero);
    });

    testWithoutContext('succeeds with coldboot launch', () async {
      final List<String> kEmulatorLaunchColdBootCommand = <String>[
        ...kEmulatorLaunchCommand,
        '-no-snapshot-load'
      ];
      final AndroidEmulator emulator = AndroidEmulator(emulatorID,
        processManager: FakeProcessManager.list(<FakeCommand>[
          FakeCommand(command: kEmulatorLaunchColdBootCommand),
        ]),
        androidSdk: mockSdk,
        logger: BufferLogger.test(),
      );

      await emulator.launch(startupDuration: Duration.zero, coldBoot: true);
    });

    testWithoutContext('prints error on failure', () async {
      final BufferLogger logger =  BufferLogger.test();
      final AndroidEmulator emulator = AndroidEmulator(emulatorID,
        processManager: FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(
            command: kEmulatorLaunchCommand,
            exitCode: 1,
            stderr: errorText,
            stdout: 'dummy text',
          ),
        ]),
        androidSdk: mockSdk,
        logger: logger,
      );

      await emulator.launch(startupDuration: Duration.zero);

      expect(logger.errorText, contains(errorText));
    });

    testWithoutContext('prints nothing on late failure with empty stderr', () async {
      final BufferLogger logger =  BufferLogger.test();
      final AndroidEmulator emulator = AndroidEmulator(emulatorID,
        processManager: FakeProcessManager.list(<FakeCommand>[
          FakeCommand(
            command: kEmulatorLaunchCommand,
            exitCode: 1,
            stdout: 'dummy text',
            completer: Completer<void>(),
          ),
        ]),
        androidSdk: mockSdk,
        logger: logger,
      );
      await emulator.launch(startupDuration: Duration.zero);

      expect(logger.errorText, isEmpty);
    });

    testWithoutContext('throws if emulator not found', () async {
      mockSdk.emulatorPath = null;

      final AndroidEmulator emulator = AndroidEmulator(
        emulatorID,
        processManager: FakeProcessManager.empty(),
        androidSdk: mockSdk,
        logger: BufferLogger.test(),
      );

      await expectLater(
        () => emulator.launch(startupDuration: Duration.zero),
        throwsA(isException.having(
          (Exception exception) => exception.toString(),
          'description',
          contains('Emulator is missing from the Android SDK'),
        )),
      );
    });
  });
}

class FakeAndroidSdk extends Fake implements AndroidSdk {
  @override
  String? emulatorPath;
}
