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

import '../application_package.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../desktop_device.dart';
import '../device.dart';
import '../device_port_forwarder.dart';
import '../features.dart';
import '../project.dart';
import 'application_package.dart';
import 'build_windows.dart';
import 'uwptool.dart';
import 'windows_workflow.dart';

/// A device that represents a desktop Windows target.
class WindowsDevice extends DesktopDevice {
  WindowsDevice({
    required ProcessManager processManager,
    required Logger logger,
    required FileSystem fileSystem,
    required OperatingSystemUtils operatingSystemUtils,
  }) : super(
      'windows',
      platformType: PlatformType.windows,
      ephemeral: false,
      processManager: processManager,
      logger: logger,
      fileSystem: fileSystem,
      operatingSystemUtils: operatingSystemUtils,
  );

  @override
  bool isSupported() => true;

  @override
  String get name => 'Windows';

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

  @override
  bool isSupportedForProject(FlutterProject flutterProject) {
    return flutterProject.windows.existsSync();
  }

  @override
  Future<void> buildForDevice(
    covariant WindowsApp package, {
    String? mainPath,
    required BuildInfo buildInfo,
  }) async {
    await buildWindows(
      FlutterProject.current().windows,
      buildInfo,
      target: mainPath,
    );
  }

  @override
  String executablePathForDevice(covariant WindowsApp package, BuildMode buildMode) {
    return package.executable(buildMode);
  }
}

// A device that represents a desktop Windows UWP target.
class WindowsUWPDevice extends Device {
  WindowsUWPDevice({
    required ProcessManager processManager,
    required Logger logger,
    required FileSystem fileSystem,
    required OperatingSystemUtils operatingSystemUtils,
    required UwpTool uwptool,
  }) : _logger = logger,
       _processManager = processManager,
       _operatingSystemUtils = operatingSystemUtils,
       _fileSystem = fileSystem,
       _uwptool = uwptool,
       super(
         'winuwp',
         platformType: PlatformType.windows,
         ephemeral: false,
         category: Category.desktop,
       );

  final ProcessManager _processManager;
  final Logger _logger;
  final FileSystem _fileSystem;
  final OperatingSystemUtils _operatingSystemUtils;
  final UwpTool _uwptool;
  BuildMode? _buildMode;

  int? _processId;

  @override
  bool isSupported() => true;

  @override
  String get name => 'Windows (UWP)';

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

  @override
  bool isSupportedForProject(FlutterProject flutterProject) {
    return flutterProject.windowsUwp.existsSync();
  }

  @override
  void clearLogs() { }

  @override
  Future<void> dispose() async { }

  @override
  Future<String?> get emulatorId async => null;

  @override
  FutureOr<DeviceLogReader> getLogReader({covariant BuildableUwpApp? app, bool includePastLogs = false}) {
    return NoOpDeviceLogReader('winuwp');
  }

  // Returns `true` if the specified file is a valid package based on file extension.
  bool _isValidPackage(String packagePath) {
    const List<String> validPackageExtensions = <String>[
      '.appx', '.msix',                // Architecture-specific application.
      '.appxbundle', '.msixbundle',    // Architecture-independent application.
      '.eappx', '.emsix',              // Encrypted architecture-specific application.
      '.eappxbundle', '.emsixbundle',  // Encrypted architecture-independent application.
    ];
    return validPackageExtensions.any(packagePath.endsWith);
  }

  // Walks the build directory for any dependent packages for the specified architecture.
  List<String> _getPackagePaths(String directory) {
    if (!_fileSystem.isDirectorySync(directory)) {
      return <String>[];
    }
    final List<String> packagePaths = <String>[];
    for (final FileSystemEntity entity in _fileSystem.directory(directory).listSync()) {
      if (entity.statSync().type != FileSystemEntityType.file) {
        continue;
      }
      final String packagePath = entity.absolute.path;
      if (_isValidPackage(packagePath)) {
        packagePaths.add(packagePath);
      }
    }
    return packagePaths;
  }

  // Walks the build directory for any dependent packages for the specified architecture.
  String? _getAppPackagePath(String buildDirectory) {
    final List<String> packagePaths = _getPackagePaths(buildDirectory);
    return packagePaths.isNotEmpty ? packagePaths.first : null;
  }

  // Walks the build directory for any dependent packages for the specified architecture.
  List<String> _getDependencyPaths(String buildDirectory, String architecture) {
    final String depsDirectory = _fileSystem.path.join(buildDirectory, 'Dependencies', architecture);
    return _getPackagePaths(depsDirectory);
  }

  String _getPackageName(String binaryName, String version, String config, {String? architecture}) {
    final List<String> components = <String>[
      binaryName,
      version,
      if (architecture != null) architecture,
      config,
    ];
    return components.join('_');
  }

  @override
  Future<bool> installApp(covariant BuildableUwpApp app, {String? userIdentifier}) async {
    /// The cmake build generates an install powershell script.
    /// build\winuwp\runner_uwp\AppPackages\<app-name>\<app-name>_<app-version>_<cmake-config>\Add-AppDevPackage.ps1
    final String? binaryName = app.name;
    final String? packageVersion = app.projectVersion;
    if (binaryName == null || packageVersion == null) {
      return false;
    }
    final String binaryDir = _fileSystem.path.absolute(
        _fileSystem.path.join('build', 'winuwp', 'runner_uwp', 'AppPackages', binaryName));
    final String config = sentenceCase(getNameForBuildMode(_buildMode ?? BuildMode.debug));

    // If a multi-architecture package exists, install that; otherwise install
    // the single-architecture package.
    final List<String> packageNames = <String>[
      // Multi-archtitecture package.
      _getPackageName(binaryName, packageVersion, config),
      // Single-archtitecture package.
      _getPackageName(binaryName, packageVersion, config, architecture: 'x64'),
    ];
    String? packageName;
    String? buildDirectory;
    String? packagePath;
    for (final String name in packageNames) {
      packageName = name;
      buildDirectory = _fileSystem.path.join(binaryDir, '${packageName}_Test');
      if (_fileSystem.isDirectorySync(buildDirectory)) {
        packagePath = _getAppPackagePath(buildDirectory);
        if (packagePath != null && _fileSystem.isFileSync(packagePath)) {
          break;
        }
      }
    }
    if (packagePath == null) {
      _logger.printError('Failed to locate app package to install');
      return false;
    }

    // Verify package signature.
    if (!await _uwptool.isSignatureValid(packagePath)) {
      // If signature is invalid, install the developer certificate.
      final String certificatePath = _fileSystem.path.join(buildDirectory!, '$packageName.cer');
      if (_logger.terminal.stdinHasTerminal) {
        final String response = await _logger.terminal.promptForCharInput(
          <String>['Y', 'y', 'N', 'n'],
          logger: _logger,
          prompt: 'Install developer certificate.\n'
          '\n'
          'Windows UWP apps are signed with a developer certificate during the build\n'
          'process. On the first install of an app with a signature from a new\n'
          'certificate, the certificate must be installed.\n'
          '\n'
          'If desired, this certificate can later be removed by launching the \n'
          '"Manage Computer Certificates" control panel from the Start menu and deleting\n'
          'the "CMake Test Cert" certificate from the "Trusted People" > "Certificates"\n'
          'section.\n'
          '\n'
          'Press "Y" to continue, or "N" to cancel.',
          displayAcceptedCharacters: false,
        );
        if (response == 'N' || response == 'n') {
          return false;
        }
      }
      await _uwptool.installCertificate(certificatePath);
    }

    // Install the application and dependencies.
    final String packageUri = Uri.file(packagePath).toString();
    final List<String> dependencyUris = _getDependencyPaths(buildDirectory!, 'x64')
        .map((String path) => Uri.file(path).toString())
        .toList();
    return _uwptool.installApp(packageUri, dependencyUris);
  }

  @override
  Future<bool> isAppInstalled(covariant ApplicationPackage app, {String? userIdentifier}) async {
    final String packageName = app.id;
    return await _uwptool.getPackageFamilyName(packageName) != null;
  }

  @override
  Future<bool> isLatestBuildInstalled(covariant ApplicationPackage app) async => false;

  @override
  Future<bool> get isLocalEmulator async => false;

  @override
  DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();

  @override
  Future<String> get sdkNameAndVersion async => '';

  @override
  Future<LaunchResult> startApp(covariant BuildableUwpApp package, {
    String? mainPath,
    String? route,
    required DebuggingOptions debuggingOptions,
    Map<String, Object?> platformArgs = const <String, Object>{},
    bool prebuiltApplication = false,
    bool ipv6 = false,
    String? userIdentifier,
  }) async {
    _buildMode = debuggingOptions.buildInfo.mode;
    if (!prebuiltApplication) {
      await buildWindowsUwp(
        package.project,
        debuggingOptions.buildInfo,
        target: mainPath,
      );
    }
    if (await isAppInstalled(package) && !await uninstallApp(package)) {
      _logger.printError('Failed to uninstall previous app package');
      return LaunchResult.failed();
    }
    if (!await installApp(package)) {
      _logger.printError('Failed to install app package');
      return LaunchResult.failed();
    }

    final String packageName = package.id;
    if (packageName == null) {
      _logger.printError('Could not find PACKAGE_GUID in ${package.project.runnerCmakeFile.path}');
      return LaunchResult.failed();
    }

    final String? packageFamily = await _uwptool.getPackageFamilyName(packageName);
    if (packageFamily == null) {
      _logger.printError('Could not find package family name from $packageName');
      return LaunchResult.failed();
    }

    if (debuggingOptions.buildInfo.mode.isRelease) {
      _processId = await _uwptool.launchApp(packageFamily, <String>[]);
      return _processId != null ? LaunchResult.succeeded() : LaunchResult.failed();
    }

    /// If the terminal is attached, prompt the user to open the firewall port.
    if (_logger.terminal.stdinHasTerminal) {
      final String response = await _logger.terminal.promptForCharInput(
        <String>['Y', 'y', 'N', 'n'],
        logger: _logger,
        prompt: 'Enable Flutter debugging from localhost.\n'
        '\n'
        'Windows UWP apps run in a sandboxed environment. To enable Flutter debugging\n'
        'and hot reload, you will need to enable inbound connections to the app from the\n'
        'Flutter tool running on your machine. To do so:\n'
        '  1. Launch PowerShell as an Administrator\n'
        '  2. Enter the following command:\n'
        '     checknetisolation loopbackexempt -is -n=$packageFamily\n'
        '\n'
        'Press "Y" once this is complete, or "N" to abort.',
        displayAcceptedCharacters: false,
      );
      if (response == 'N' || response == 'n') {
        return LaunchResult.failed();
      }
    }

    /// Currently we do not have a way to discover the VM Service URI.
    final int port = debuggingOptions.deviceVmServicePort ?? await _operatingSystemUtils.findFreePort();
    final List<String> args = <String>[
      '--observatory-port=$port',
      '--disable-service-auth-codes',
      '--enable-dart-profiling',
      if (debuggingOptions.startPaused) '--start-paused',
      if (debuggingOptions.useTestFonts) '--use-test-fonts',
      if (debuggingOptions.debuggingEnabled) ...<String>[
        '--enable-checked-mode',
        '--verify-entry-points',
      ],
      if (debuggingOptions.enableSoftwareRendering) '--enable-software-rendering',
      if (debuggingOptions.skiaDeterministicRendering) '--skia-deterministic-rendering',
      if (debuggingOptions.traceSkia) '--trace-skia',
      if (debuggingOptions.traceAllowlist != null) '--trace-allowlist="${debuggingOptions.traceAllowlist}"',
      if (debuggingOptions.traceSkiaAllowlist != null) '--trace-skia-allowlist="${debuggingOptions.traceSkiaAllowlist}"',
      if (debuggingOptions.endlessTraceBuffer) '--endless-trace-buffer',
      if (debuggingOptions.dumpSkpOnShaderCompilation) '--dump-skp-on-shader-compilation',
      if (debuggingOptions.verboseSystemLogs) '--verbose-logging',
      if (debuggingOptions.cacheSkSL) '--cache-sksl',
      if (debuggingOptions.purgePersistentCache) '--purge-persistent-cache',
      if (platformArgs['trace-startup'] as bool? ?? false) '--trace-startup',
    ];
    _processId = await _uwptool.launchApp(packageFamily, args);
    if (_processId == null) {
      return LaunchResult.failed();
    }
    return LaunchResult.succeeded(observatoryUri: Uri.parse('http://localhost:$port'));
  }

  @override
  Future<bool> stopApp(covariant BuildableUwpApp app, {String? userIdentifier}) async {
    if (_processId != null) {
      return _processManager.killPid(_processId!);
    }
    return false;
  }

  @override
  Future<bool> uninstallApp(covariant BuildableUwpApp app, {String? userIdentifier}) async {
    final String packageName = app.id;
    if (packageName == null) {
      _logger.printError('Could not find PACKAGE_GUID in ${app.project.runnerCmakeFile.path}');
      return false;
    }
    final String? packageFamily = await _uwptool.getPackageFamilyName(packageName);
    if (packageFamily == null) {
      // App is not installed.
      return true;
    }
    return _uwptool.uninstallApp(packageFamily);
  }

  @override
  FutureOr<bool> supportsRuntimeMode(BuildMode buildMode) => buildMode != BuildMode.jitRelease;
}

class WindowsDevices extends PollingDeviceDiscovery {
  WindowsDevices({
    required ProcessManager processManager,
    required Logger logger,
    required FileSystem fileSystem,
    required OperatingSystemUtils operatingSystemUtils,
    required WindowsWorkflow windowsWorkflow,
    required FeatureFlags featureFlags,
    required UwpTool uwptool,
  }) : _fileSystem = fileSystem,
      _logger = logger,
      _processManager = processManager,
      _operatingSystemUtils = operatingSystemUtils,
      _windowsWorkflow = windowsWorkflow,
      _featureFlags = featureFlags,
      _uwptool = uwptool,
      super('windows devices');

  final FileSystem _fileSystem;
  final Logger _logger;
  final ProcessManager _processManager;
  final OperatingSystemUtils _operatingSystemUtils;
  final WindowsWorkflow _windowsWorkflow;
  final FeatureFlags _featureFlags;
  final UwpTool _uwptool;

  @override
  bool get supportsPlatform => _windowsWorkflow.appliesToHostPlatform;

  @override
  bool get canListAnything => _windowsWorkflow.canListDevices;

  @override
  Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
    if (!canListAnything) {
      return const <Device>[];
    }
    return <Device>[
      WindowsDevice(
        fileSystem: _fileSystem,
        logger: _logger,
        processManager: _processManager,
        operatingSystemUtils: _operatingSystemUtils,
      ),
      if (_featureFlags.isWindowsUwpEnabled)
        WindowsUWPDevice(
          fileSystem: _fileSystem,
          logger: _logger,
          processManager: _processManager,
          operatingSystemUtils: _operatingSystemUtils,
          uwptool: _uwptool,
        )
    ];
  }

  @override
  Future<List<String>> getDiagnostics() async => const <String>[];

  @override
  List<String> get wellKnownIds => const <String>['windows', 'winuwp'];
}
