// 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 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/build_info.dart';

import '../integration.shard/test_utils.dart';
import '../src/common.dart';
import '../src/darwin_common.dart';

void main() {
  group('iOS app validation', () {
    late String flutterRoot;
    late Directory pluginRoot;
    late String projectRoot;
    late String flutterBin;
    late Directory tempDir;
    late File hiddenFile;

    setUpAll(() {
      flutterRoot = getFlutterRoot();
      tempDir = createResolvedTempDirectorySync('ios_content_validation.');
      flutterBin = fileSystem.path.join(
        flutterRoot,
        'bin',
        'flutter',
      );

      final Directory xcframeworkArtifact = fileSystem.directory(
        fileSystem.path.join(
          flutterRoot,
          'bin',
          'cache',
          'artifacts',
          'engine',
          'ios',
          'Flutter.xcframework',
        ),
      );

      // Pre-cache iOS engine Flutter.xcframework artifacts.
      processManager.runSync(<String>[
        flutterBin,
        ...getLocalEngineArguments(),
        'precache',
        '--ios',
      ], workingDirectory: tempDir.path);

      // Pretend the SDK was on an external drive with stray "._" files in the xcframework
      hiddenFile = xcframeworkArtifact.childFile('._Info.plist')..createSync();

      // Test a plugin example app to allow plugins validation.
      processManager.runSync(<String>[
        flutterBin,
        ...getLocalEngineArguments(),
        'create',
        '--verbose',
        '--platforms=ios',
        '-t',
        'plugin',
        'hello',
      ], workingDirectory: tempDir.path);

      pluginRoot = tempDir.childDirectory('hello');
      projectRoot = pluginRoot.childDirectory('example').path;
    });

    tearDownAll(() {
      tryToDelete(hiddenFile);
      tryToDelete(tempDir);
    });

    for (final BuildMode buildMode in <BuildMode>[BuildMode.debug, BuildMode.release]) {
      group('build in ${buildMode.name} mode', () {
        late Directory outputPath;
        late Directory outputApp;
        late Directory frameworkDirectory;
        late Directory outputFlutterFramework;
        late File outputFlutterFrameworkBinary;
        late Directory outputAppFramework;
        late File outputAppFrameworkBinary;
        late File outputPluginFrameworkBinary;
        late Directory buildPath;
        late Directory buildAppFrameworkDsym;
        late File buildAppFrameworkDsymBinary;
        late ProcessResult buildResult;

        setUpAll(() {
          buildResult = processManager.runSync(<String>[
            flutterBin,
            ...getLocalEngineArguments(),
            'build',
            'ios',
            '--verbose',
            '--no-codesign',
            '--${buildMode.name}',
            '--obfuscate',
            '--split-debug-info=foo debug info/',
          ], workingDirectory: projectRoot);

          outputPath = fileSystem.directory(fileSystem.path.join(
            projectRoot,
            'build',
            'ios',
            'iphoneos',
          ));

          outputApp = outputPath.childDirectory('Runner.app');

          frameworkDirectory = outputApp.childDirectory('Frameworks');
          outputFlutterFramework = frameworkDirectory.childDirectory('Flutter.framework');
          outputFlutterFrameworkBinary = outputFlutterFramework.childFile('Flutter');

          outputAppFramework = frameworkDirectory.childDirectory('App.framework');
          outputAppFrameworkBinary = outputAppFramework.childFile('App');

          outputPluginFrameworkBinary = frameworkDirectory.childDirectory('hello.framework').childFile('hello');

          buildPath = fileSystem.directory(fileSystem.path.join(
            projectRoot,
            'build',
            'ios',
            '${sentenceCase(buildMode.name)}-iphoneos',
          ));

          buildAppFrameworkDsym = buildPath.childDirectory('App.framework.dSYM');
          buildAppFrameworkDsymBinary = buildAppFrameworkDsym.childFile('Contents/Resources/DWARF/App');
        });

        testWithoutContext('flutter build ios builds a valid app', () {
          printOnFailure('Output of flutter build ios:');
          printOnFailure(buildResult.stdout.toString());
          printOnFailure(buildResult.stderr.toString());
          expect(buildResult.exitCode, 0);

          expect(outputPluginFrameworkBinary, exists);

          expect(outputAppFrameworkBinary, exists);
          expect(outputAppFramework.childFile('Info.plist'), exists);

          expect(buildAppFrameworkDsymBinary.existsSync(), buildMode != BuildMode.debug);

          final File vmSnapshot = fileSystem.file(fileSystem.path.join(
            outputAppFramework.path,
            'flutter_assets',
            'vm_snapshot_data',
          ));

          expect(vmSnapshot.existsSync(), buildMode == BuildMode.debug);

          // Archiving should contain a bitcode blob, but not building.
          // This mimics Xcode behavior and prevents a developer from having to install a
          // 300+MB app.
          expect(containsBitcode(outputFlutterFrameworkBinary.path, processManager), isFalse);
        });

        testWithoutContext('Info.plist dart observatory Bonjour service', () {
          final String infoPlistPath = fileSystem.path.join(
            outputApp.path,
            'Info.plist',
          );
          final ProcessResult bonjourServices = processManager.runSync(
            <String>[
              'plutil',
              '-extract',
              'NSBonjourServices',
              'xml1',
              '-o',
              '-',
              infoPlistPath,
            ],
          );
          final bool bonjourServicesFound = (bonjourServices.stdout as String).contains('_dartobservatory._tcp');
          expect(bonjourServicesFound, buildMode == BuildMode.debug);

          final ProcessResult localNetworkUsage = processManager.runSync(
            <String>[
              'plutil',
              '-extract',
              'NSLocalNetworkUsageDescription',
              'xml1',
              '-o',
              '-',
              infoPlistPath,
            ],
          );
          final bool localNetworkUsageFound = localNetworkUsage.exitCode == 0;
          expect(localNetworkUsageFound, buildMode == BuildMode.debug);
        });

        testWithoutContext('check symbols', () {
          final List<String> symbols =
              AppleTestUtils.getExportedSymbols(outputAppFrameworkBinary.path);
          if (buildMode == BuildMode.debug) {
            expect(symbols, isEmpty);
          } else {
            expect(symbols, equals(AppleTestUtils.requiredSymbols));
          }
        });

        testWithoutContext('check symbols in dSYM', () {
          if (buildMode == BuildMode.debug) {
            // dSYM is not created for a debug build.
            expect(buildAppFrameworkDsymBinary.existsSync(), isFalse);
          } else {
            final List<String> symbols =
                AppleTestUtils.getExportedSymbols(buildAppFrameworkDsymBinary.path);
            expect(symbols, containsAll(AppleTestUtils.requiredSymbols));
            // The actual number of symbols is going to vary but there should
            // be "many" in the dSYM. At the time of writing, it was 7656.
            expect(symbols.length, greaterThanOrEqualTo(5000));
          }
        });

        testWithoutContext('xcode_backend embed_and_thin', () {
          outputFlutterFramework.deleteSync(recursive: true);
          outputAppFramework.deleteSync(recursive: true);
          expect(outputFlutterFrameworkBinary.existsSync(), isFalse);
          expect(outputAppFrameworkBinary.existsSync(), isFalse);

          final String xcodeBackendPath = fileSystem.path.join(
            flutterRoot,
            'packages',
            'flutter_tools',
            'bin',
            'xcode_backend.sh',
          );

          // Simulate a common Xcode build setting misconfiguration
          // where FLUTTER_APPLICATION_PATH is missing
          final ProcessResult xcodeBackendResult = processManager.runSync(
            <String>[
              xcodeBackendPath,
              'embed_and_thin',
            ],
            environment: <String, String>{
              'SOURCE_ROOT': fileSystem.path.join(projectRoot, 'ios'),
              'BUILT_PRODUCTS_DIR': fileSystem.path.join(
                projectRoot,
                'build',
                'ios',
                'Release-iphoneos',
              ),
              'TARGET_BUILD_DIR': outputPath.path,
              'FRAMEWORKS_FOLDER_PATH': 'Runner.app/Frameworks',
              'VERBOSE_SCRIPT_LOGGING': '1',
              'FLUTTER_BUILD_MODE': 'release',
              'ACTION': 'install',
              // Skip bitcode stripping since we just checked that above.
            },
          );
          printOnFailure('Output of xcode_backend.sh:');
          printOnFailure(xcodeBackendResult.stdout.toString());
          printOnFailure(xcodeBackendResult.stderr.toString());

          expect(xcodeBackendResult.exitCode, 0);
          expect(outputFlutterFrameworkBinary.existsSync(), isTrue);
          expect(outputAppFrameworkBinary.existsSync(), isTrue);
        }, skip: !platform.isMacOS || buildMode != BuildMode.release); // [intended] only makes sense on macos.

        testWithoutContext('validate obfuscation', () {
          // HelloPlugin class is present in project.
          ProcessResult grepResult = processManager.runSync(<String>[
            'grep',
            '-r',
            'HelloPlugin',
            pluginRoot.path,
          ]);
          // Matches exits 0.
          expect(grepResult.exitCode, 0);

          // Not present in binary.
          grepResult = processManager.runSync(<String>[
            'grep',
            'HelloPlugin',
            outputAppFrameworkBinary.path,
          ]);
          // Does not match exits 1.
          expect(grepResult.exitCode, 1);
        });
      });
    }

    testWithoutContext('builds all plugin architectures for simulator', () {
      final ProcessResult buildSimulator = processManager.runSync(
        <String>[
          flutterBin,
          ...getLocalEngineArguments(),
          'build',
          'ios',
          '--simulator',
          '--verbose',
          '--no-codesign',
        ],
        workingDirectory: projectRoot,
      );
      expect(buildSimulator.exitCode, 0);

      final File pluginFrameworkBinary = fileSystem.file(fileSystem.path.join(
        projectRoot,
        'build',
        'ios',
        'iphonesimulator',
        'Runner.app',
        'Frameworks',
        'hello.framework',
        'hello',
      ));
      expect(pluginFrameworkBinary, exists);
      final ProcessResult archs = processManager.runSync(
        <String>['file', pluginFrameworkBinary.path],
      );
      expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library x86_64'));
      expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library arm64'));
    });

    testWithoutContext('build for simulator with all available architectures', () {
      final ProcessResult buildSimulator = processManager.runSync(
        <String>[
          flutterBin,
          ...getLocalEngineArguments(),
          'build',
          'ios',
          '--simulator',
          '--verbose',
          '--no-codesign',
        ],
        workingDirectory: projectRoot,
        environment: <String, String>{
          'FLUTTER_XCODE_ONLY_ACTIVE_ARCH': 'NO',
        },
      );
      // This test case would fail if arm64 or x86_64 simulators could not build.
      expect(buildSimulator.exitCode, 0);

      final File simulatorAppFrameworkBinary = fileSystem.file(fileSystem.path.join(
        projectRoot,
        'build',
        'ios',
        'iphonesimulator',
        'Runner.app',
        'Frameworks',
        'App.framework',
        'App',
      ));
      expect(simulatorAppFrameworkBinary, exists);
      final ProcessResult archs = processManager.runSync(
        <String>['file', simulatorAppFrameworkBinary.path],
      );
      expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library x86_64'));
      expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library arm64'));
    });
  }, skip: !platform.isMacOS, // [intended] only makes sense for macos platform.
     timeout: const Timeout(Duration(minutes: 7))
  );
}
