// Copyright 2013 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.

// @dart = 2.6
import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:collection/collection.dart' show MapEquality;

// This script verifies that the release binaries only export the expected
// symbols.
//
// Android binaries (libflutter.so) should only export one symbol "JNI_OnLoad"
// of type "T".
//
// iOS binaries (Flutter.framework/Flutter) should only export Objective-C
// Symbols from the Flutter namespace. These are either of type
// "(__DATA,__common)" or "(__DATA,__objc_data)".

/// Takes the path to the out directory as the first argument, and the path to
/// the buildtools directory as the second argument.
///
/// If the second argument is not specified, it is assumed that it is the parent
/// of the out directory (for backwards compatibility).
void main(List<String> arguments) {
  assert(arguments.length == 2 || arguments.length == 1);
  final String outPath = arguments.first;
  final String buildToolsPath = arguments.length == 1
      ? p.join(p.dirname(outPath), 'buildtools')
      : arguments[1];

  String platform;
  if (Platform.isLinux) {
    platform = 'linux-x64';
  } else if (Platform.isMacOS) {
    platform = 'mac-x64';
  } else {
    throw UnimplementedError('Script only support running on Linux or MacOS.');
  }
  final String nmPath = p.join(buildToolsPath, platform, 'clang', 'bin', 'llvm-nm');
  assert(Directory(outPath).existsSync());

  final Iterable<String> releaseBuilds = Directory(outPath).listSync()
      .where((FileSystemEntity entity) => entity is Directory)
      .map<String>((FileSystemEntity dir) => p.basename(dir.path))
      .where((String s) => s.contains('_release'));

  final Iterable<String> iosReleaseBuilds = releaseBuilds
      .where((String s) => s.startsWith('ios_'));
  final Iterable<String> androidReleaseBuilds = releaseBuilds
      .where((String s) => s.startsWith('android_'));

  int failures = 0;
  failures += _checkIos(outPath, nmPath, iosReleaseBuilds);
  failures += _checkAndroid(outPath, nmPath, androidReleaseBuilds);
  print('Failing checks: $failures');
  exit(failures);
}

int _checkIos(String outPath, String nmPath, Iterable<String> builds) {
  int failures = 0;
  for (String build in builds) {
    final String libFlutter = p.join(outPath, build, 'Flutter.framework', 'Flutter');
    if (!File(libFlutter).existsSync()) {
      print('SKIPPING: $libFlutter does not exist.');
      continue;
    }
    final ProcessResult nmResult = Process.runSync(nmPath, <String>['-gUm', libFlutter]);
    if (nmResult.exitCode != 0) {
      print('ERROR: failed to execute "nm -gUm $libFlutter":\n${nmResult.stderr}');
      failures++;
      continue;
    }
    final Iterable<NmEntry> unexpectedEntries = NmEntry.parse(nmResult.stdout).where((NmEntry entry) {
      return !(((entry.type == '(__DATA,__common)' || entry.type == '(__DATA,__const)') && entry.name.startsWith('_Flutter'))
          || (entry.type == '(__DATA,__objc_data)'
              && (entry.name.startsWith('_OBJC_METACLASS_\$_Flutter') || entry.name.startsWith('_OBJC_CLASS_\$_Flutter'))));
    });
    if (unexpectedEntries.isNotEmpty) {
      print('ERROR: $libFlutter exports unexpected symbols:');
      print(unexpectedEntries.fold<String>('', (String previous, NmEntry entry) {
        return '${previous == '' ? '' : '$previous\n'}     ${entry.type} ${entry.name}';
      }));
      failures++;
    } else {
      print('OK: $libFlutter');
    }
  }
  return failures;
}

int _checkAndroid(String outPath, String nmPath, Iterable<String> builds) {
  int failures = 0;
  for (String build in builds) {
    final String libFlutter = p.join(outPath, build, 'libflutter.so');
    if (!File(libFlutter).existsSync()) {
      print('SKIPPING: $libFlutter does not exist.');
      continue;
    }
    final ProcessResult nmResult = Process.runSync(nmPath, <String>['-gU', libFlutter]);
    if (nmResult.exitCode != 0) {
      print('ERROR: failed to execute "nm -gU $libFlutter":\n${nmResult.stderr}');
      failures++;
      continue;
    }
    final Iterable<NmEntry> entries = NmEntry.parse(nmResult.stdout);
    final Map<String, String> entryMap = Map<String, String>.fromIterable(
        entries,
        key: (dynamic entry) => entry.name,
        value: (dynamic entry) => entry.type);
    final Map<String, String> expectedSymbols = <String, String>{
      'JNI_OnLoad': 'T',
      '_binary_icudtl_dat_size': 'A',
      '_binary_icudtl_dat_start': 'D',
      // TODO(fxb/47943): Remove these once Clang lld does not expose them.
      // arm
      '__adddf3': 'T',
      '__addsf3': 'T',
      '__aeabi_cdcmpeq': 'T',
      '__aeabi_cdcmple': 'T',
      '__aeabi_cdrcmple': 'T',
      '__aeabi_cfcmpeq': 'T',
      '__aeabi_cfcmple': 'T',
      '__aeabi_cfrcmple': 'T',
      '__aeabi_d2lz': 'T',
      '__aeabi_d2uiz': 'T',
      '__aeabi_d2ulz': 'T',
      '__aeabi_dadd': 'T',
      '__aeabi_dcmpeq': 'T',
      '__aeabi_dcmpge': 'T',
      '__aeabi_dcmpgt': 'T',
      '__aeabi_dcmple': 'T',
      '__aeabi_dcmplt': 'T',
      '__aeabi_ddiv': 'T',
      '__aeabi_dmul': 'T',
      '__aeabi_drsub': 'T',
      '__aeabi_dsub': 'T',
      '__aeabi_f2d': 'T',
      '__aeabi_f2lz': 'T',
      '__aeabi_f2ulz': 'T',
      '__aeabi_fadd': 'T',
      '__aeabi_fcmpeq': 'T',
      '__aeabi_fcmpge': 'T',
      '__aeabi_fcmpgt': 'T',
      '__aeabi_fcmple': 'T',
      '__aeabi_fcmplt': 'T',
      '__aeabi_frsub': 'T',
      '__aeabi_fsub': 'T',
      '__aeabi_i2d': 'T',
      '__aeabi_i2f': 'T',
      '__aeabi_l2d': 'T',
      '__aeabi_l2f': 'T',
      '__aeabi_lasr': 'T',
      '__aeabi_ldivmod': 'T',
      '__aeabi_llsl': 'T',
      '__aeabi_llsr': 'T',
      '__aeabi_ui2d': 'T',
      '__aeabi_ui2f': 'T',
      '__aeabi_uidiv': 'T',
      '__aeabi_uidivmod': 'T',
      '__aeabi_ul2d': 'T',
      '__aeabi_ul2f': 'T',
      '__aeabi_uldivmod': 'T',
      '__ashldi3': 'T',
      '__ashrdi3': 'T',
      '__cmpdf2': 'T',
      '__cmpsf2': 'T',
      '__divdf3': 'T',
      '__divdi3': 'T',
      '__eqdf2': 'T',
      '__eqsf2': 'T',
      '__extendsfdf2': 'T',
      '__fixdfdi': 'T',
      '__fixsfdi': 'T',
      '__fixunsdfdi': 'T',
      '__fixunsdfsi': 'T',
      '__fixunssfdi': 'T',
      '__floatdidf': 'T',
      '__floatdisf': 'T',
      '__floatsidf': 'T',
      '__floatsisf': 'T',
      '__floatundidf': 'T',
      '__floatundisf': 'T',
      '__floatunsidf': 'T',
      '__floatunsisf': 'T',
      '__gedf2': 'T',
      '__gesf2': 'T',
      '__gnu_ldivmod_helper': 'T',
      '__gnu_uldivmod_helper': 'T',
      '__gtdf2': 'T',
      '__gtsf2': 'T',
      '__ledf2': 'T',
      '__lesf2': 'T',
      '__lshrdi3': 'T',
      '__ltdf2': 'T',
      '__ltsf2': 'T',
      '__muldf3': 'T',
      '__nedf2': 'T',
      '__nesf2': 'T',
      '__subdf3': 'T',
      '__subsf3': 'T',
      '__udivdi3': 'T',
      '__udivsi3': 'T',
      // arm64
      '__clz_tab': 'R',
      '__udivti3': 'T',
      // arm64 && x64
      '__emutls_get_address': 'T',
      '__emutls_register_common': 'T',
      // jit x86
      '__moddi3': 'T',
      '__umoddi3': 'T',
    };
    final Map<String, String> badSymbols = <String, String>{};
    for (final String key in entryMap.keys) {
      if (entryMap[key] != expectedSymbols[key]) {
        badSymbols[key] = entryMap[key];
      }
    }
    if (badSymbols.isNotEmpty) {
      print('ERROR: $libFlutter exports the wrong symbols');
      print(' Expected $expectedSymbols');
      print(' Library has $entryMap.');
      failures++;
    } else {
      print('OK: $libFlutter');
    }
  }
  return failures;
}

class NmEntry {
  NmEntry._(this.address, this.type, this.name);

  final String address;
  final String type;
  final String name;

  static Iterable<NmEntry> parse(String stdout) {
    return LineSplitter.split(stdout).map((String line) {
      final List<String> parts = line.split(' ');
      return NmEntry._(parts[0], parts[1], parts.last);
    });
  }
}
