// Copyright 2020 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' as io;

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:process/process.dart';
import 'package:logging/logging.dart';
import 'package:platform/platform.dart';

class DiagnoseCommand extends Command<bool> {
  DiagnoseCommand({
    this.processManager = const LocalProcessManager(),
    Logger? loggerOverride,
  }) : logger = loggerOverride ?? Logger.root;

  final Logger logger;

  final ProcessManager processManager;

  final String name = 'diagnose';
  final String description = 'Diagnose whether attached iOS devices have errors.';

  Future<bool> run() async {
    final List<String> command = <String>['xcrun', 'xcdevice', 'list'];
    final io.ProcessResult result = await processManager.run(
      command,
    );
    if (result.exitCode != 0) {
      logger.severe(
        '$command failed with exit code ${result.exitCode}\n${result.stderr}',
      );
      return false;
    }
    final String stdout = result.stdout as String;
    logger.info(stdout);
    final Iterable<XCDevice> devices = XCDevice.parseJson(stdout);
    final Iterable<XCDevice> devicesWithErrors = devices.where((XCDevice device) => device.hasError);

    if (devicesWithErrors.isNotEmpty) {
      logger.severe('Found devices with errors!');

      for (final XCDevice device in devicesWithErrors) {
        logger.severe('${device.name}: ${device.error}');
      }
      return false;
    }

    return true;
  }
}

class RecoverCommand extends Command<bool> {
  RecoverCommand({
    this.processManager = const LocalProcessManager(),
    Logger? loggerOverride,
    this.fs = const LocalFileSystem(),
    this.platform = const LocalPlatform(),
  }) : logger = loggerOverride ?? Logger.root {
    argParser
      ..addOption(
        'cocoon-root',
        help: 'Path to the root of the Cocoon repo. This is used to find the Build dashboard macos project, which is '
            'then used to open Xcode.',
        mandatory: true,
      )
      ..addOption(
        'timeout',
        help: 'Integer number of seconds to allow Xcode to run before killing it.',
        defaultsTo: '300',
      );
  }

  final Logger logger;
  final ProcessManager processManager;
  final FileSystem fs;
  final Platform platform;

  final String name = 'recover';
  final String description = 'Open Xcode UI to allow it to sync debug symbols from the iPhone';

  /// Xcode Project workspace file for the build dashboard Flutter app.
  ///
  /// Should be located at //cocoon/dashboard/ios/Runner.xcodeproj/project.xcworkspace.
  Directory get dashboardXcWorkspace {
    final String cocoonRootPath = argResults!['cocoon-root'];
    final Directory cocoonRoot = fs.directory(cocoonRootPath);
    final Directory dashboardXcWorkspace = cocoonRoot
        .childDirectory('dashboard')
        .childDirectory('ios')
        .childDirectory('Runner.xcodeproj')
        .childDirectory('project.xcworkspace')
        .absolute;
    if (!dashboardXcWorkspace.existsSync()) {
      throw StateError(
        'You provided the --cocoon-root option with "$cocoonRootPath", and the device doctor tried to '
        "locate the build dashboard's project.xcworkspace directory at \"${dashboardXcWorkspace.path}\" "
        'but that path does not exist on disk.',
      );
    }
    return dashboardXcWorkspace;
  }

  @override
  Future<bool> run() async {
    final int? timeoutSeconds = int.tryParse(argResults!['timeout']);
    if (timeoutSeconds == null) {
      throw ArgumentError('Could not parse an integer from the option --timeout="${argResults!['timeout']}"');
    }

    _deleteSymbols();

    // Prompt Xcode to first setup without opening the app.
    // This will return very quickly if there is no work to do.
    logger.info('Running Xcode first launch...');
    final io.ProcessResult runFirstLaunchResult = await processManager.run(<String>[
      'xcrun',
      'xcodebuild',
      '-runFirstLaunch',
    ]);
    final String runFirstLaunchStdout = runFirstLaunchResult.stdout.trim();
    if (runFirstLaunchStdout.isNotEmpty) {
      logger.info('stdout from `xcodebuild -runFirstLaunch`:\n$runFirstLaunchStdout\n');
    }
    final String runFirstLaunchStderr = runFirstLaunchResult.stderr.trim();
    if (runFirstLaunchStderr.isNotEmpty) {
      logger.info('stderr from `xcodebuild -runFirstLaunch`:\n$runFirstLaunchStderr\n');
    }
    final int runFirstLaunchCode = runFirstLaunchResult.exitCode;
    if (runFirstLaunchCode != 0) {
      logger.info('Failed running `xcodebuild -runFirstLaunch` with code $runFirstLaunchCode!');
      return false;
    }

    final Duration timeout = Duration(seconds: timeoutSeconds);
    logger.info('Launching Xcode...');
    final Future<io.ProcessResult> xcodeFuture = processManager.run(<String>[
      'open',
      '-n', // Opens a new instance of the application even if one is already running
      '-F', // Opens the application "fresh," without restoring windows
      '-W', // Wait for the opened application (Xcode) to close
      dashboardXcWorkspace.path,
    ]);

    unawaited(
      xcodeFuture.then((io.ProcessResult result) {
        logger.info('Open closed...');
        final String stdout = result.stdout.trim();
        if (stdout.isNotEmpty) {
          logger.info('stdout from `open`:\n$stdout\n');
        }
        final String stderr = result.stderr.trim();
        if (stderr.isNotEmpty) {
          logger.info('stderr from `open`:\n$stderr\n');
        }
        if (result.exitCode != 0) {
          throw Exception('Failed opening Xcode!');
        }
      }),
    );

    logger.info('Waiting for $timeoutSeconds seconds');
    await Future.delayed(timeout);
    logger.info('Waited for $timeoutSeconds seconds, now killing Xcode');
    final io.ProcessResult result = await processManager.run(<String>['killall', '-9', 'Xcode']);

    if (result.exitCode != 0) {
      logger.severe('Failed killing Xcode!');
      return false;
    }
    return true;
  }

  /// Delete all symbols by deleting the `iOS DeviceSupport` directory.
  /// Xcode will regenerate this folder and symbols for connected devices
  /// when Xcode is opened.
  void _deleteSymbols() {
    final String? home = platform.environment['HOME'];
    if (home == null) {
      logger.warning('\$HOME path was not found');
      return;
    }
    final Directory deviceSupportDirectory = fs.directory('$home/Library/Developer/Xcode/iOS DeviceSupport');
    if (!deviceSupportDirectory.existsSync()) {
      logger.warning('iOS Device Support directory was not found at ${deviceSupportDirectory.path}');
      return;
    }
    logger.info('Deleting iOS DeviceSupport...');
    try {
      deviceSupportDirectory.deleteSync(recursive: true);
    } on FileSystemException catch (e) {
      // Error that indicates why files cannot be deleted, such as
      // another program having the files open.
      logger.severe('${e.message}: ${e.osError}');
    }
  }
}

/// A Device configuration as output by `xcrun xcdevice list`.
///
/// As more fields are needed, they can be added to this class. It is
/// recommended to make all fields nullable in case a different version of Xcode
/// does not implement it.
class XCDevice {
  const XCDevice._({
    required this.error,
    required this.name,
  });

  static const String _debugSymbolDescriptionPattern = r' is busy: Fetching debug symbols for ';
  static final RegExp _preparingPhoneForDevelopmentPattern = RegExp(
    r'Preparing .* for development\. Xcode will continue when .* is finished\.',
  );

  /// Parse subset of JSON from `parseJson` associated with a particular XCDevice.
  factory XCDevice.fromMap(Map<String, Object?> map) {
    final Map<String, Object?>? error = map['error'] as Map<String, Object?>?;
    // We should only specifically pattern match on known fatal errors, and
    // ignore the rest.
    bool validError = false;
    if (error != null) {
      final String description = error['description'] as String;
      if (description.contains(_debugSymbolDescriptionPattern) ||
          _preparingPhoneForDevelopmentPattern.hasMatch(description)) {
        validError = true;
      } else {
        print('not matching pattern: $description');
      }
    }
    return XCDevice._(
      error: validError ? error : null,
      name: map['name'] as String,
    );
  }

  final Map<String, Object?>? error;
  final String name;

  bool get hasError => error != null;

  /// Parse the complete output of `xcrun xcdevice list`.
  static Iterable<XCDevice> parseJson(String jsonString) {
    final List<Object?> devices = json.decode(jsonString) as List<Object?>;
    return devices.map<XCDevice>((Object? obj) {
      return XCDevice.fromMap(obj as Map<String, Object?>);
    });
  }
}
