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

import '../base/common.dart';
import '../base/error_handling_io.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/process.dart';
import '../base/template.dart';
import '../convert.dart';
import '../macos/xcode.dart';
import '../template.dart';

/// A class to handle interacting with Xcode via OSA (Open Scripting Architecture)
/// Scripting to debug Flutter applications.
class XcodeDebug {
  XcodeDebug({
    required Logger logger,
    required ProcessManager processManager,
    required Xcode xcode,
    required FileSystem fileSystem,
  })  : _logger = logger,
        _processUtils = ProcessUtils(logger: logger, processManager: processManager),
        _xcode = xcode,
        _fileSystem = fileSystem;

  final ProcessUtils _processUtils;
  final Logger _logger;
  final Xcode _xcode;
  final FileSystem _fileSystem;

  /// Process to start Xcode's debug action.
  @visibleForTesting
  Process? startDebugActionProcess;

  /// Information about the project that is currently being debugged.
  @visibleForTesting
  XcodeDebugProject? currentDebuggingProject;

  /// Whether the debug action has been started.
  bool get debugStarted => currentDebuggingProject != null;

  /// Install, launch, and start a debug session for app through Xcode interface,
  /// automated by OSA scripting. First checks if the project is opened in
  /// Xcode. If it isn't, open it with the `open` command.
  ///
  /// The OSA script waits until the project is opened and the debug action
  /// has started. It does not wait for the app to install, launch, or start
  /// the debug session.
  Future<bool> debugApp({
    required XcodeDebugProject project,
    required String deviceId,
    required List<String> launchArguments,
  }) async {
    // If project is not already opened in Xcode, open it.
    if (!await _isProjectOpenInXcode(project: project)) {
      final bool openResult = await _openProjectInXcode(xcodeWorkspace: project.xcodeWorkspace);
      if (!openResult) {
        return openResult;
      }
    }

    currentDebuggingProject = project;
    StreamSubscription<String>? stdoutSubscription;
    StreamSubscription<String>? stderrSubscription;
    try {
      startDebugActionProcess = await _processUtils.start(
        <String>[
          ..._xcode.xcrunCommand(),
          'osascript',
          '-l',
          'JavaScript',
          _xcode.xcodeAutomationScriptPath,
          'debug',
          '--xcode-path',
          _xcode.xcodeAppPath,
          '--project-path',
          project.xcodeProject.path,
          '--workspace-path',
          project.xcodeWorkspace.path,
          '--project-name',
          project.hostAppProjectName,
          if (project.expectedConfigurationBuildDir != null)
            ...<String>[
              '--expected-configuration-build-dir',
              project.expectedConfigurationBuildDir!,
            ],
          '--device-id',
          deviceId,
          '--scheme',
          project.scheme,
          '--skip-building',
          '--launch-args',
          json.encode(launchArguments),
          if (project.verboseLogging) '--verbose',
        ],
      );

      final StringBuffer stdoutBuffer = StringBuffer();
      stdoutSubscription = startDebugActionProcess!.stdout
          .transform<String>(utf8.decoder)
          .transform<String>(const LineSplitter())
          .listen((String line) {
            _logger.printTrace(line);
            stdoutBuffer.write(line);
      });

      final StringBuffer stderrBuffer = StringBuffer();
      bool permissionWarningPrinted = false;
      // console.log from the script are found in the stderr
      stderrSubscription = startDebugActionProcess!.stderr
          .transform<String>(utf8.decoder)
          .transform<String>(const LineSplitter())
          .listen((String line) {
            _logger.printTrace('stderr: $line');
            stderrBuffer.write(line);

          // This error may occur if Xcode automation has not been allowed.
          // Example: Failed to get workspace: Error: An error occurred.
          if (!permissionWarningPrinted && line.contains('Failed to get workspace') && line.contains('An error occurred')) {
            _logger.printError(
              'There was an error finding the project in Xcode. Ensure permission '
              'has been given to control Xcode in Settings > Privacy & Security > Automation.',
            );
            permissionWarningPrinted = true;
          }
      });

      final int exitCode = await startDebugActionProcess!.exitCode.whenComplete(() async {
        await stdoutSubscription?.cancel();
        await stderrSubscription?.cancel();
        startDebugActionProcess = null;
      });

      if (exitCode != 0) {
        _logger.printError('Error executing osascript: $exitCode\n$stderrBuffer');
        return false;
      }

      final XcodeAutomationScriptResponse? response = parseScriptResponse(
        stdoutBuffer.toString(),
      );
      if (response == null) {
        return false;
      }
      if (response.status == false) {
        _logger.printError('Error starting debug session in Xcode: ${response.errorMessage}');
        return false;
      }
      if (response.debugResult == null) {
        _logger.printError('Unable to get debug results from response: $stdoutBuffer');
        return false;
      }
      if (response.debugResult?.status != 'running') {
        _logger.printError(
          'Unexpected debug results: \n'
          '  Status: ${response.debugResult?.status}\n'
          '  Completed: ${response.debugResult?.completed}\n'
          '  Error Message: ${response.debugResult?.errorMessage}\n'
        );
        return false;
      }
      return true;
    } on ProcessException catch (exception) {
      _logger.printError('Error executing osascript: $exitCode\n$exception');
      await stdoutSubscription?.cancel();
      await stderrSubscription?.cancel();
      startDebugActionProcess = null;

      return false;
    }
  }

  /// Kills [startDebugActionProcess] if it's still running. If [force] is true, it
  /// will kill all Xcode app processes. Otherwise, it will stop the debug
  /// session in Xcode. If the project is temporary, it will close the Xcode
  /// window of the project and then delete the project.
  Future<bool> exit({
    bool force = false,
    @visibleForTesting
    bool skipDelay = false,
  }) async {
    final bool success = (startDebugActionProcess == null) || startDebugActionProcess!.kill();

    if (force) {
      await _forceExitXcode();
      if (currentDebuggingProject != null) {
        final XcodeDebugProject project = currentDebuggingProject!;
        if (project.isTemporaryProject) {
          // Only delete if it exists. This is to prevent crashes when racing
          // with shutdown hooks to delete temporary files.
          ErrorHandlingFileSystem.deleteIfExists(
            project.xcodeProject.parent,
            recursive: true,
          );
        }
        currentDebuggingProject = null;
      }
    }

    if (currentDebuggingProject != null) {
      final XcodeDebugProject project = currentDebuggingProject!;
      await stopDebuggingApp(
        project: project,
        closeXcode: project.isTemporaryProject,
      );

      if (project.isTemporaryProject) {
        // Wait a couple seconds before deleting the project. If project is
        // still opened in Xcode and it's deleted, it will prompt the user to
        // restore it.
        if (!skipDelay) {
          await Future<void>.delayed(const Duration(seconds: 2));
        }

        try {
          project.xcodeProject.parent.deleteSync(recursive: true);
        } on FileSystemException {
          _logger.printError('Failed to delete temporary Xcode project: ${project.xcodeProject.parent.path}');
        }
      }
      currentDebuggingProject = null;
    }

    return success;
  }

  /// Kill all opened Xcode applications.
  Future<bool> _forceExitXcode() async {
    final RunResult result = await _processUtils.run(
      <String>[
        'killall',
        '-9',
        'Xcode',
      ],
    );

    if (result.exitCode != 0) {
      _logger.printError('Error killing Xcode: ${result.exitCode}\n${result.stderr}');
      return false;
    }
    return true;
  }

  Future<bool> _isProjectOpenInXcode({
    required XcodeDebugProject project,
  }) async {

    final RunResult result = await _processUtils.run(
      <String>[
        ..._xcode.xcrunCommand(),
        'osascript',
        '-l',
        'JavaScript',
        _xcode.xcodeAutomationScriptPath,
        'check-workspace-opened',
        '--xcode-path',
        _xcode.xcodeAppPath,
        '--project-path',
        project.xcodeProject.path,
        '--workspace-path',
        project.xcodeWorkspace.path,
        if (project.verboseLogging) '--verbose',
      ],
    );

    if (result.exitCode != 0) {
      _logger.printError('Error executing osascript: ${result.exitCode}\n${result.stderr}');
      return false;
    }

    final XcodeAutomationScriptResponse? response = parseScriptResponse(result.stdout);
    if (response == null) {
      return false;
    }
    if (response.status == false) {
      _logger.printTrace('Error checking if project opened in Xcode: ${response.errorMessage}');
      return false;
    }
    return true;
  }

  @visibleForTesting
  XcodeAutomationScriptResponse? parseScriptResponse(String results) {
    try {
      final Object decodeResult = json.decode(results) as Object;
      if (decodeResult is Map<String, Object?>) {
        final XcodeAutomationScriptResponse response = XcodeAutomationScriptResponse.fromJson(decodeResult);
        // Status should always be found
        if (response.status != null) {
          return response;
        }
      }
      _logger.printError('osascript returned unexpected JSON response: $results');
      return null;
    } on FormatException {
      _logger.printError('osascript returned non-JSON response: $results');
      return null;
    }
  }

  Future<bool> _openProjectInXcode({
    required Directory xcodeWorkspace,
  }) async {
    try {
      await _processUtils.run(
        <String>[
          'open',
          '-a',
          _xcode.xcodeAppPath,
          '-g', // Do not bring the application to the foreground.
          '-j', // Launches the app hidden.
          '-F', // Open "fresh", without restoring windows.
          xcodeWorkspace.path
        ],
        throwOnError: true,
      );
      return true;
    } on ProcessException catch (error, stackTrace) {
      _logger.printError('$error', stackTrace: stackTrace);
    }
    return false;
  }

  /// Using OSA Scripting, stop the debug session in Xcode.
  ///
  /// If [closeXcode] is true, it will close the Xcode window that has the
  /// project opened. If [promptToSaveOnClose] is true, it will ask the user if
  /// they want to save any changes before it closes.
  Future<bool> stopDebuggingApp({
    required XcodeDebugProject project,
    bool closeXcode = false,
    bool promptToSaveOnClose = false,
  }) async {
    final RunResult result = await _processUtils.run(
      <String>[
        ..._xcode.xcrunCommand(),
        'osascript',
        '-l',
        'JavaScript',
        _xcode.xcodeAutomationScriptPath,
        'stop',
        '--xcode-path',
        _xcode.xcodeAppPath,
        '--project-path',
        project.xcodeProject.path,
        '--workspace-path',
        project.xcodeWorkspace.path,
        if (closeXcode) '--close-window',
        if (promptToSaveOnClose) '--prompt-to-save',
        if (project.verboseLogging) '--verbose',
      ],
    );

    if (result.exitCode != 0) {
      _logger.printError('Error executing osascript: ${result.exitCode}\n${result.stderr}');
      return false;
    }

    final XcodeAutomationScriptResponse? response = parseScriptResponse(result.stdout);
    if (response == null) {
      return false;
    }
    if (response.status == false) {
      _logger.printError('Error stopping app in Xcode: ${response.errorMessage}');
      return false;
    }
    return true;
  }

  /// Create a temporary empty Xcode project with the application bundle
  /// location explicitly set.
  Future<XcodeDebugProject> createXcodeProjectWithCustomBundle(
    String deviceBundlePath, {
    required TemplateRenderer templateRenderer,
    @visibleForTesting
    Directory? projectDestination,
    bool verboseLogging = false,
  }) async {
    final Directory tempXcodeProject = projectDestination ?? _fileSystem.systemTempDirectory.createTempSync('flutter_empty_xcode.');

    final Template template = await Template.fromName(
      _fileSystem.path.join('xcode', 'ios', 'custom_application_bundle'),
      fileSystem: _fileSystem,
      templateManifest: null,
      logger: _logger,
      templateRenderer: templateRenderer,
    );

    template.render(
      tempXcodeProject,
      <String, Object>{
        'applicationBundlePath': deviceBundlePath
      },
      printStatusWhenWriting: false,
    );

    return XcodeDebugProject(
      scheme: 'Runner',
      hostAppProjectName: 'Runner',
      xcodeProject: tempXcodeProject.childDirectory('Runner.xcodeproj'),
      xcodeWorkspace: tempXcodeProject.childDirectory('Runner.xcworkspace'),
      isTemporaryProject: true,
      verboseLogging: verboseLogging,
    );
  }

  /// Ensure the Xcode project is set up to launch an LLDB debugger. If these
  /// settings are not set, the launch will fail with a "Cannot create a
  /// FlutterEngine instance in debug mode without Flutter tooling or Xcode."
  /// error message. These settings should be correct by default, but some users
  /// reported them not being so after upgrading to Xcode 15.
  void ensureXcodeDebuggerLaunchAction(File schemeFile) {
    if (!schemeFile.existsSync()) {
      _logger.printError('Failed to find ${schemeFile.path}');
      return;
    }

    final String schemeXml = schemeFile.readAsStringSync();
    try {
      final XmlDocument document = XmlDocument.parse(schemeXml);
      final Iterable<XmlNode> nodes = document.xpath('/Scheme/LaunchAction');
      if (nodes.isEmpty) {
        _logger.printError('Failed to find LaunchAction for the Scheme in ${schemeFile.path}.');
        return;
      }
      final XmlNode launchAction = nodes.first;
      final XmlAttribute? debuggerIdentifier = launchAction.attributes
          .where((XmlAttribute attribute) =>
              attribute.localName == 'selectedDebuggerIdentifier')
          .firstOrNull;
      final XmlAttribute? launcherIdentifier = launchAction.attributes
          .where((XmlAttribute attribute) =>
              attribute.localName == 'selectedLauncherIdentifier')
          .firstOrNull;
      if (debuggerIdentifier == null ||
          launcherIdentifier == null ||
          !debuggerIdentifier.value.contains('LLDB') ||
          !launcherIdentifier.value.contains('LLDB')) {
        throwToolExit('''
Your Xcode project is not setup to start a debugger. To fix this, launch Xcode
and select "Product > Scheme > Edit Scheme", select "Run" in the sidebar,
and ensure "Debug executable" is checked in the "Info" tab.
''');
      }
    } on XmlException catch (exception) {
      _logger.printError('Failed to parse ${schemeFile.path}: $exception');
    }
  }
}

@visibleForTesting
class XcodeAutomationScriptResponse {
  XcodeAutomationScriptResponse._({
    this.status,
    this.errorMessage,
    this.debugResult,
  });

  factory XcodeAutomationScriptResponse.fromJson(Map<String, Object?> data) {
    XcodeAutomationScriptDebugResult? debugResult;
    if (data['debugResult'] != null && data['debugResult'] is Map<String, Object?>) {
      debugResult = XcodeAutomationScriptDebugResult.fromJson(
        data['debugResult']! as Map<String, Object?>,
      );
    }
    return XcodeAutomationScriptResponse._(
      status: data['status'] is bool? ? data['status'] as bool? : null,
      errorMessage: data['errorMessage']?.toString(),
      debugResult: debugResult,
    );
  }

  final bool? status;
  final String? errorMessage;
  final XcodeAutomationScriptDebugResult? debugResult;
}

@visibleForTesting
class XcodeAutomationScriptDebugResult {
  XcodeAutomationScriptDebugResult._({
    required this.completed,
    required this.status,
    required this.errorMessage,
  });

  factory XcodeAutomationScriptDebugResult.fromJson(Map<String, Object?> data) {
    return XcodeAutomationScriptDebugResult._(
      completed: data['completed'] is bool? ? data['completed'] as bool? : null,
      status: data['status']?.toString(),
      errorMessage: data['errorMessage']?.toString(),
    );
  }

  /// Whether this scheme action has completed (successfully or otherwise). Will
  /// be false if still running.
  final bool? completed;

  /// The status of the debug action. Potential statuses include:
  /// `not yet started`, `‌running`, `‌cancelled`, `‌failed`, `‌error occurred`,
  /// and `‌succeeded`.
  ///
  /// Only the status of `‌running` indicates the debug action has started successfully.
  /// For example, `‌succeeded` often does not indicate success as if the action fails,
  /// it will sometimes return `‌succeeded`.
  final String? status;

  /// When [status] is `‌error occurred`, an error message is provided.
  /// Otherwise, this will be null.
  final String? errorMessage;
}

class XcodeDebugProject {
  XcodeDebugProject({
    required this.scheme,
    required this.xcodeWorkspace,
    required this.xcodeProject,
    required this.hostAppProjectName,
    this.expectedConfigurationBuildDir,
    this.isTemporaryProject = false,
    this.verboseLogging = false,
  });

  final String scheme;
  final Directory xcodeWorkspace;
  final Directory xcodeProject;
  final String hostAppProjectName;
  final String? expectedConfigurationBuildDir;
  final bool isTemporaryProject;

  /// When [verboseLogging] is true, the xcode_debug.js script will log
  /// additional information via console.log, which is sent to stderr.
  final bool verboseLogging;
}
