// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. 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:io';

import 'package:code_assets/code_assets.dart';
import 'package:dartdev/src/native_assets_bundling.dart';

final _rpathUri = Uri.file('@rpath/');

Future<void> rewriteInstallNames(
  List<Uri> dylibs, {
  required bool relocatable,
}) async {
  final oldToNewInstallNames = <String, String>{};
  final dylibInfos = <(Uri, String)>[];

  await Future.wait(dylibs.map((dylib) async {
    final newInstallName = relocatable
        ? _rpathUri
            .resolveUri(libOutputDirectoryUri)
            .resolve(dylib.pathSegments.last)
            .toFilePath()
        : dylib.toFilePath();
    final oldInstallName = await _getInstallName(dylib);
    oldToNewInstallNames[oldInstallName] = newInstallName;
    dylibInfos.add((dylib, newInstallName));
  }));

  await Future.wait(dylibInfos.map((info) async {
    final (dylib, newInstallName) = info;
    await _setInstallNames(dylib, newInstallName, oldToNewInstallNames);
    await _codeSignDylib(dylib);
  }));
}

Future<String> _getInstallName(Uri dylib) async {
  final otoolResult = await Process.run(
    'otool',
    [
      '-D',
      dylib.toFilePath(),
    ],
  );
  if (otoolResult.exitCode != 0) {
    throw Exception(
      'Failed to get install name for dylib $dylib: ${otoolResult.stderr}',
    );
  }
  final architectureSections =
      parseOtoolArchitectureSections(otoolResult.stdout);
  if (architectureSections.length != 1) {
    throw Exception(
      'Expected a single architecture section in otool output: $otoolResult',
    );
  }
  return architectureSections.values.first.single;
}

Future<void> _setInstallNames(
  Uri dylib,
  String newInstallName,
  Map<String, String> oldToNewInstallNames,
) async {
  final installNameToolResult = await Process.run(
    'install_name_tool',
    [
      '-id',
      newInstallName,
      for (final entry in oldToNewInstallNames.entries) ...[
        '-change',
        entry.key,
        entry.value,
      ],
      dylib.toFilePath(),
    ],
  );
  if (installNameToolResult.exitCode != 0) {
    throw Exception(
      'Failed to set install names for dylib $dylib:\n'
      'id -> $newInstallName\n'
      'dependencies -> $oldToNewInstallNames\n'
      '${installNameToolResult.stderr}',
    );
  }
}

Future<void> _codeSignDylib(Uri dylib) async {
  final codesignResult = await Process.run(
    'codesign',
    [
      '--force',
      '--sign',
      '-',
      dylib.toFilePath(),
    ],
  );
  if (codesignResult.exitCode != 0) {
    throw Exception(
      'Failed to codesign dylib $dylib: ${codesignResult.stderr}',
    );
  }
}

Map<Architecture?, List<String>> parseOtoolArchitectureSections(String output) {
  // The output of `otool -D`, for example, looks like below. For each
  // architecture, there is a separate section.
  //
  // /build/native_assets/ios/buz.framework/buz (architecture x86_64):
  // @rpath/libbuz.dylib
  // /build/native_assets/ios/buz.framework/buz (architecture arm64):
  // @rpath/libbuz.dylib
  //
  // Some versions of `otool` don't print the architecture name if the
  // binary only has one architecture:
  //
  // /build/native_assets/ios/buz.framework/buz:
  // @rpath/libbuz.dylib

  const Map<String, Architecture> outputArchitectures = <String, Architecture>{
    'arm': Architecture.arm,
    'arm64': Architecture.arm64,
    'x86_64': Architecture.x64,
  };
  final RegExp architectureHeaderPattern =
      RegExp(r'^[^(]+( \(architecture (.+)\))?:$');
  final Iterator<String> lines = output.trim().split('\n').iterator;
  Architecture? currentArchitecture;
  final Map<Architecture?, List<String>> architectureSections =
      <Architecture?, List<String>>{};

  while (lines.moveNext()) {
    final String line = lines.current;
    final Match? architectureHeader =
        architectureHeaderPattern.firstMatch(line);
    if (architectureHeader != null) {
      if (architectureSections.containsKey(null)) {
        throw Exception(
          'Expected a single architecture section in otool output: $output',
        );
      }
      final String? architectureString = architectureHeader.group(2);
      if (architectureString != null) {
        currentArchitecture = outputArchitectures[architectureString];
        if (currentArchitecture == null) {
          throw Exception(
            'Unknown architecture in otool output: $architectureString',
          );
        }
      }
      architectureSections[currentArchitecture] = <String>[];
      continue;
    } else {
      architectureSections[currentArchitecture]!.add(line.trim());
    }
  }

  return architectureSections;
}

/// Rewrites the include path for an executable on MacOS.
///
/// The directory structure for `dart build cli` is
///
/// ```
/// bundle/
///   bin/
///     <executable>
///   lib/
///     <dylibs>
/// ```
///
/// So, the `bundle/` directory must be added to the include path to allow for
/// loading dylibs.
Future<void> rewriteInstallPath(Uri executable) async {
  final result = await Process.run(
    'install_name_tool',
    ['-add_rpath', '@executable_path/..', executable.toFilePath()],
  );
  if (result.exitCode != 0) {
    throw Exception(
      'Failed to add rpath: ${result.stderr}',
    );
  }

  // Resign after modifying.
  final codesignResult = await Process.run(
    'codesign',
    [
      '--force',
      '--sign',
      '-',
      executable.toFilePath(),
    ],
  );
  if (codesignResult.exitCode != 0) {
    throw Exception(
      'Failed to codesign dylib $executable: ${codesignResult.stderr}',
    );
  }
}
