// 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:meta/meta.dart';
import 'package:process/process.dart';

import '../android/android_sdk.dart';
import '../android/android_workflow.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/process.dart';
import '../base/utils.dart';
import '../convert.dart';
import '../device.dart';
import '../emulator.dart';
import 'android_sdk.dart';

class AndroidEmulators extends EmulatorDiscovery {
  AndroidEmulators({
    @required AndroidSdk androidSdk,
    @required AndroidWorkflow androidWorkflow,
    @required FileSystem fileSystem,
    @required Logger logger,
    @required ProcessManager processManager,
  }) : _androidSdk = androidSdk,
       _androidWorkflow = androidWorkflow,
       _fileSystem = fileSystem,
       _logger = logger,
       _processManager = processManager,
       _processUtils = ProcessUtils(logger: logger, processManager: processManager);

  final AndroidWorkflow _androidWorkflow;
  final AndroidSdk _androidSdk;
  final FileSystem _fileSystem;
  final Logger _logger;
  final ProcessManager _processManager;
  final ProcessUtils _processUtils;

  @override
  bool get supportsPlatform => true;

  @override
  bool get canListAnything => _androidWorkflow.canListEmulators;

  @override
  bool get canLaunchAnything => _androidWorkflow.canListEmulators
    && _androidSdk.getAvdManagerPath() != null;

  @override
  Future<List<Emulator>> get emulators => _getEmulatorAvds();

  /// Return the list of available emulator AVDs.
  Future<List<AndroidEmulator>> _getEmulatorAvds() async {
    final String emulatorPath = _androidSdk.emulatorPath;
    if (emulatorPath == null) {
      return <AndroidEmulator>[];
    }

    final String listAvdsOutput = (await _processUtils.run(
      <String>[emulatorPath, '-list-avds'])).stdout.trim();

    final List<AndroidEmulator> emulators = <AndroidEmulator>[];
    if (listAvdsOutput != null) {
      _extractEmulatorAvdInfo(listAvdsOutput, emulators);
    }
    return emulators;
  }

  /// Parse the given `emulator -list-avds` output in [text], and fill out the given list
  /// of emulators by reading information from the relevant ini files.
  void _extractEmulatorAvdInfo(String text, List<AndroidEmulator> emulators) {
    for (final String id in text.trim().split('\n').where((String l) => l != '')) {
      emulators.add(_loadEmulatorInfo(id));
    }
  }

  AndroidEmulator _loadEmulatorInfo(String id) {
    id = id.trim();
    final String avdPath = _androidSdk.getAvdPath();
    final AndroidEmulator androidEmulatorWithoutProperties = AndroidEmulator(
      id,
      processManager: _processManager,
      logger: _logger,
      androidSdk: _androidSdk,
    );
    if (avdPath == null) {
      return androidEmulatorWithoutProperties;
    }
    final File iniFile = _fileSystem.file(_fileSystem.path.join(avdPath, '$id.ini'));
    if (!iniFile.existsSync()) {
      return androidEmulatorWithoutProperties;
    }
    final Map<String, String> ini = parseIniLines(iniFile.readAsLinesSync());
    if (ini['path'] == null) {
      return androidEmulatorWithoutProperties;
    }
    final File configFile = _fileSystem.file(_fileSystem.path.join(ini['path'], 'config.ini'));
    if (!configFile.existsSync()) {
      return androidEmulatorWithoutProperties;
    }
    final Map<String, String> properties = parseIniLines(configFile.readAsLinesSync());
    return AndroidEmulator(
      id,
      properties: properties,
      processManager: _processManager,
      logger: _logger,
      androidSdk: _androidSdk,
    );
  }
}

class AndroidEmulator extends Emulator {
  AndroidEmulator(String id, {
    Map<String, String> properties,
    @required Logger logger,
    @required AndroidSdk androidSdk,
    @required ProcessManager processManager,
  }) : _properties = properties,
       _logger = logger,
       _androidSdk = androidSdk,
       _processUtils = ProcessUtils(logger: logger, processManager: processManager),
       super(id, properties != null && properties.isNotEmpty);

  final Map<String, String> _properties;
  final Logger _logger;
  final ProcessUtils _processUtils;
  final AndroidSdk _androidSdk;

  // Android Studio uses the ID with underscores replaced with spaces
  // for the name if displayname is not set so we do the same.
  @override
  String get name => _prop('avd.ini.displayname') ?? id.replaceAll('_', ' ').trim();

  @override
  String get manufacturer => _prop('hw.device.manufacturer');

  @override
  Category get category => Category.mobile;

  @override
  PlatformType get platformType => PlatformType.android;

  String _prop(String name) => _properties != null ? _properties[name] : null;

  @override
  Future<void> launch() async {
    final Process process = await _processUtils.start(
      <String>[_androidSdk.emulatorPath, '-avd', id],
    );

    // Record output from the emulator process.
    final List<String> stdoutList = <String>[];
    final List<String> stderrList = <String>[];
    final StreamSubscription<String> stdoutSubscription = process.stdout
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen(stdoutList.add);
    final StreamSubscription<String> stderrSubscription = process.stderr
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen(stderrList.add);
    final Future<void> stdioFuture = waitGroup<void>(<Future<void>>[
      stdoutSubscription.asFuture<void>(),
      stderrSubscription.asFuture<void>(),
    ]);

    // The emulator continues running on success, so we don't wait for the
    // process to complete before continuing. However, if the process fails
    // after the startup phase (3 seconds), then we only echo its output if
    // its error code is non-zero and its stderr is non-empty.
    bool earlyFailure = true;
    unawaited(process.exitCode.then((int status) async {
      if (status == 0) {
        _logger.printTrace('The Android emulator exited successfully');
        return;
      }
      // Make sure the process' stdout and stderr are drained.
      await stdioFuture;
      unawaited(stdoutSubscription.cancel());
      unawaited(stderrSubscription.cancel());
      if (stdoutList.isNotEmpty) {
        _logger.printTrace('Android emulator stdout:');
        stdoutList.forEach(_logger.printTrace);
      }
      if (!earlyFailure && stderrList.isEmpty) {
        _logger.printStatus('The Android emulator exited with code $status');
        return;
      }
      final String when = earlyFailure ? 'during startup' : 'after startup';
      _logger.printError('The Android emulator exited with code $status $when');
      _logger.printError('Android emulator stderr:');
      stderrList.forEach(_logger.printError);
      _logger.printError('Address these issues and try again.');
    }));

    // Wait a few seconds for the emulator to start.
    await Future<void>.delayed(const Duration(seconds: 3));
    earlyFailure = false;
    return;
  }
}


@visibleForTesting
Map<String, String> parseIniLines(List<String> contents) {
  final Map<String, String> results = <String, String>{};

  final Iterable<List<String>> properties = contents
      .map<String>((String l) => l.trim())
      // Strip blank lines/comments
      .where((String l) => l != '' && !l.startsWith('#'))
      // Discard anything that isn't simple name=value
      .where((String l) => l.contains('='))
      // Split into name/value
      .map<List<String>>((String l) => l.split('='));

  for (final List<String> property in properties) {
    results[property[0].trim()] = property[1].trim();
  }

  return results;
}
