// 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/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/migrations/swift_package_manager_integration_migration.dart';

import 'package:flutter_tools/src/project.dart';
import 'package:test/fake.dart';

import '../../src/common.dart';

const List<SupportedPlatform> supportedPlatforms = <SupportedPlatform>[
  SupportedPlatform.ios,
  SupportedPlatform.macos
];

void main() {
  group('Flutter Package Migration', () {
    testWithoutContext('fails if Xcode project not found', () async {
      final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
      final BufferLogger testLogger = BufferLogger.test();

      final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
        FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        ),
        SupportedPlatform.ios,
        BuildInfo.debug,
        xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
        logger: testLogger,
        fileSystem: memoryFileSystem,
        plistParser: FakePlistParser(),
      );
      await expectLater(
        () => projectMigration.migrate(),
        throwsToolExit(message: 'Xcode project not found.'),
      );
      expect(testLogger.traceText, isEmpty);
      expect(testLogger.statusText, isEmpty);
    });

    group('get scheme file', () {
      testWithoutContext('fails if Xcode project info not found', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        final FakeXcodeProject project = FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, SupportedPlatform.ios);
        project._projectInfo = null;

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          SupportedPlatform.ios,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: FakePlistParser(),
        );
        await expectLater(
          () => projectMigration.migrate(),
          throwsToolExit(message: 'Unable to get Xcode project info.'),
        );
        expect(testLogger.traceText, isEmpty);
        expect(testLogger.statusText, isEmpty);
      });

      testWithoutContext('fails if Xcode workspace not found', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        final FakeXcodeProject project = FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, SupportedPlatform.ios);
        project.xcodeWorkspace = null;

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          SupportedPlatform.ios,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: FakePlistParser(),
        );
        await expectLater(
          () => projectMigration.migrate(),
          throwsToolExit(message: 'Xcode workspace not found.'),
        );
        expect(testLogger.traceText, isEmpty);
        expect(testLogger.statusText, isEmpty);
      });

      testWithoutContext('fails if scheme not found', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        final FakeXcodeProject project = FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, SupportedPlatform.ios);
        project._projectInfo = XcodeProjectInfo(
          <String>[],
          <String>[],
          <String>[],
          testLogger,
        );

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          SupportedPlatform.ios,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: FakePlistParser(),
        );
        await expectLater(
          () => projectMigration.migrate(),
          throwsToolExit(message: 'You must specify a --flavor option to select one of the available schemes.'),
        );
        expect(testLogger.traceText, isEmpty);
        expect(testLogger.statusText, isEmpty);
      });

      testWithoutContext('fails if scheme file not found', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        final FakeXcodeProject project = FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(
          project,
          SupportedPlatform.ios,
          createSchemeFile: false,
        );

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          SupportedPlatform.ios,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: FakePlistParser(),
        );
        await expectLater(
          () => projectMigration.migrate(),
          throwsToolExit(message: 'Unable to get scheme file for Runner.'),
        );
        expect(testLogger.traceText, isEmpty);
        expect(testLogger.statusText, isEmpty);
      });
    });

    testWithoutContext('does not migrate if already migrated', () async {
      final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
      final BufferLogger testLogger = BufferLogger.test();
      final FakeXcodeProject project = FakeXcodeProject(
        platform: SupportedPlatform.ios.name,
        fileSystem: memoryFileSystem,
        logger: testLogger,
      );
      _createProjectFiles(project, SupportedPlatform.ios);
      project.xcodeProjectSchemeFile().writeAsStringSync(
        _validBuildActions(SupportedPlatform.ios, hasFrameworkScript: true),
      );
      project.xcodeProjectInfoFile.writeAsStringSync(
        _projectSettings(_allSectionsMigrated(SupportedPlatform.ios)),
      );

      final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
        project,
        SupportedPlatform.ios,
        BuildInfo.debug,
        xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
        logger: testLogger,
        fileSystem: memoryFileSystem,
        plistParser: FakePlistParser(),
      );
      await projectMigration.migrate();
      expect(testLogger.traceText, isEmpty);
      expect(testLogger.statusText, isEmpty);
      expect(testLogger.warningText, isEmpty);
      expect(testLogger.errorText, isEmpty);
    });

    group('migrate scheme', () {
      testWithoutContext('skipped if already updated', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        final FakeXcodeProject project = FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, SupportedPlatform.ios);
        project.xcodeProjectSchemeFile().writeAsStringSync(
          _validBuildActions(SupportedPlatform.ios, hasFrameworkScript: true),
        );

        project.xcodeProjectInfoFile.writeAsStringSync('');

        final List<String> settingsAsJsonBeforeMigration = <String>[
          ..._allSectionsMigratedAsJson(SupportedPlatform.ios),
        ];
        settingsAsJsonBeforeMigration.removeAt(_buildFileSectionIndex);

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          SupportedPlatform.ios,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: FakePlistParser(
            json: _plutilOutput(settingsAsJsonBeforeMigration),
          ),
        );
        await expectLater(() => projectMigration.migrate(), throwsToolExit());
        expect(
          testLogger.traceText,
          contains('Runner.xcscheme already migrated. Skipping...'),
        );
      });

      for (final SupportedPlatform platform in supportedPlatforms) {
        group('for ${platform.name}', () {
          testWithoutContext('fails if scheme is missing BlueprintIdentifier for Runner native target', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync('');

            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: FakePlistParser(),
            );
            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Failed to parse Runner.xcscheme: Could not find BuildableReference'),
            );
          });

          testWithoutContext('fails if BuildableName does not follow BlueprintIdentifier in scheme', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync('''
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "${_runnerNativeTargetIdentifer(platform)}"
            BlueprintName = "Runner"
            ReferencedContainer = "container:Runner.xcodeproj">
         </BuildableReference>
'''
            );

            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: FakePlistParser(),
            );

            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Failed to parse Runner.xcscheme: Could not find BuildableName'),
            );
          });

          testWithoutContext('fails if BlueprintName does not follow BuildableName in scheme', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync('''
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "${_runnerNativeTargetIdentifer(platform)}"
            BuildableName = "Runner.app"
            ReferencedContainer = "container:Runner.xcodeproj">
         </BuildableReference>
'''
            );

            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: FakePlistParser(),
            );

            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Failed to parse Runner.xcscheme: Could not find BlueprintName'),
            );
          });

          testWithoutContext('fails if ReferencedContainer does not follow BlueprintName in scheme', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync('''
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "${_runnerNativeTargetIdentifer(platform)}"
            BuildableName = "Runner.app"
            BlueprintName = "Runner">
         </BuildableReference>
'''
            );

            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: FakePlistParser(),
            );

            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Failed to parse Runner.xcscheme: Could not find ReferencedContainer'),
            );
          });

          testWithoutContext('fails if cannot find BuildActionEntries in scheme', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync(
              _validBuildableReference(platform),
            );

            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: FakePlistParser(),
            );

            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Failed to parse Runner.xcscheme: Could not find BuildActionEntries'),
            );
          });

          testWithoutContext('fails if updated scheme is not valid xml', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync(
              '${_validBuildActions(platform)} <an opening without a close>',
            );
            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: FakePlistParser(),
            );

            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Failed to parse Runner.xcscheme: Invalid xml:'),
            );
          });

          testWithoutContext('successfully updates scheme with preexisting PreActions', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync(
              _validBuildActions(platform, hasPreActions: true),
            );
            final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
              _plutilOutput(_allSectionsMigratedAsJson(platform)),
              _plutilOutput(_allSectionsMigratedAsJson(platform)),
            ]);
            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: plistParser,
            );

            await projectMigration.migrate();
            expect(
              project.xcodeProjectSchemeFile().readAsStringSync(),
              _validBuildActions(platform, hasFrameworkScript: true),
            );
          });

          testWithoutContext('successfully updates scheme with no preexisting PreActions', () async {
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectSchemeFile().writeAsStringSync(
              _validBuildActions(platform),
            );

            final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
              _plutilOutput(_allSectionsMigratedAsJson(platform)),
              _plutilOutput(_allSectionsMigratedAsJson(platform)),
            ]);
            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: plistParser,
            );

            await projectMigration.migrate();
            expect(
              project.xcodeProjectSchemeFile().readAsStringSync(),
              _validBuildActions(platform, hasFrameworkScript: true),
            );
          });
        });
      }
    });

    group('migrate pbxproj', () {
      testWithoutContext('skipped if already updated', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        final FakeXcodeProject project = FakeXcodeProject(
          platform: SupportedPlatform.ios.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, SupportedPlatform.ios);

        project.xcodeProjectInfoFile.writeAsStringSync(
          _projectSettings(_allSectionsMigrated(SupportedPlatform.ios)),
        );

        final List<String> settingsAsJsonBeforeMigration = <String>[
          ..._allSectionsMigratedAsJson(SupportedPlatform.ios),
        ];
        settingsAsJsonBeforeMigration.removeAt(_buildFileSectionIndex);

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          SupportedPlatform.ios,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: FakePlistParser(
            json: _plutilOutput(settingsAsJsonBeforeMigration),
          ),
        );
        await projectMigration.migrate();
        expect(
          testLogger.traceText,
          contains('project.pbxproj already migrated. Skipping...'),
        );
      });

      group('fails if parsing project.pbxproj', () {
        testWithoutContext('fails plutil command', () async {
          final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
          final BufferLogger testLogger = BufferLogger.test();
          final FakeXcodeProject project = FakeXcodeProject(
            platform: SupportedPlatform.ios.name,
            fileSystem: memoryFileSystem,
            logger: testLogger,
          );
          _createProjectFiles(project, SupportedPlatform.ios);

          final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
            project,
            SupportedPlatform.ios,
            BuildInfo.debug,
            xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
            logger: testLogger,
            fileSystem: memoryFileSystem,
            plistParser: FakePlistParser(),
          );
          await expectLater(
            () => projectMigration.migrate(),
            throwsToolExit(message: 'Failed to parse project settings.'),
          );
        });

        testWithoutContext('returns unexpected JSON', () async {
          final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
          final BufferLogger testLogger = BufferLogger.test();
          final FakeXcodeProject project = FakeXcodeProject(
            platform: SupportedPlatform.ios.name,
            fileSystem: memoryFileSystem,
            logger: testLogger,
          );
          _createProjectFiles(project, SupportedPlatform.ios);

          final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
            project,
            SupportedPlatform.ios,
            BuildInfo.debug,
            xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
            logger: testLogger,
            fileSystem: memoryFileSystem,
            plistParser: FakePlistParser(json: '[]'),
          );
          await expectLater(
            () => projectMigration.migrate(),
            throwsToolExit(message: 'project.pbxproj returned unexpected JSON response'),
          );
        });

        testWithoutContext('returns non-JSON', () async {
          final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
          final BufferLogger testLogger = BufferLogger.test();
          final FakeXcodeProject project = FakeXcodeProject(
            platform: SupportedPlatform.ios.name,
            fileSystem: memoryFileSystem,
            logger: testLogger,
          );
          _createProjectFiles(project, SupportedPlatform.ios);

          final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
            project,
            SupportedPlatform.ios,
            BuildInfo.debug,
            xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
            logger: testLogger,
            fileSystem: memoryFileSystem,
            plistParser: FakePlistParser(json: 'this is not json'),
          );
          await expectLater(
            () => projectMigration.migrate(),
            throwsToolExit(message: 'project.pbxproj returned non-JSON response'),
          );
        });
      });

      group('fails if duplicate id', () {
        testWithoutContext('for PBXBuildFile', () async {
          final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
          final BufferLogger testLogger = BufferLogger.test();
          final FakeXcodeProject project = FakeXcodeProject(
            platform: SupportedPlatform.ios.name,
            fileSystem: memoryFileSystem,
            logger: testLogger,
          );
          _createProjectFiles(project, SupportedPlatform.ios);
          project.xcodeProjectInfoFile.writeAsStringSync('78A318202AECB46A00862997');

          final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
            project,
            SupportedPlatform.ios,
            BuildInfo.debug,
            xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
            logger: testLogger,
            fileSystem: memoryFileSystem,
            plistParser: FakePlistParser(),
          );
          expect(
            () => projectMigration.migrate(),
            throwsToolExit(message: 'Duplicate id found for PBXBuildFile'),
          );
        });

        testWithoutContext('for XCSwiftPackageProductDependency', () async {
          final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
          final BufferLogger testLogger = BufferLogger.test();
          final FakeXcodeProject project = FakeXcodeProject(
            platform: SupportedPlatform.ios.name,
            fileSystem: memoryFileSystem,
            logger: testLogger,
          );
          _createProjectFiles(project, SupportedPlatform.ios);
          project.xcodeProjectInfoFile.writeAsStringSync('78A3181F2AECB46A00862997');

          final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
            project,
            SupportedPlatform.ios,
            BuildInfo.debug,
            xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
            logger: testLogger,
            fileSystem: memoryFileSystem,
            plistParser: FakePlistParser(),
          );
          expect(
            () => projectMigration.migrate(),
            throwsToolExit(message: 'Duplicate id found for XCSwiftPackageProductDependency'),
          );
        });

        testWithoutContext('for XCLocalSwiftPackageReference', () async {
          final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
          final BufferLogger testLogger = BufferLogger.test();
          final FakeXcodeProject project = FakeXcodeProject(
            platform: SupportedPlatform.ios.name,
            fileSystem: memoryFileSystem,
            logger: testLogger,
          );
          _createProjectFiles(project, SupportedPlatform.ios);
          project.xcodeProjectInfoFile.writeAsStringSync('781AD8BC2B33823900A9FFBB');

          final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
            project,
            SupportedPlatform.ios,
            BuildInfo.debug,
            xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
            logger: testLogger,
            fileSystem: memoryFileSystem,
            plistParser: FakePlistParser(),
          );
          expect(
            () => projectMigration.migrate(),
            throwsToolExit(message: 'Duplicate id found for XCLocalSwiftPackageReference'),
          );
        });
      });

      for (final SupportedPlatform platform in supportedPlatforms) {
        group('for ${platform.name}', () {
          group('migrate PBXBuildFile', () {
            testWithoutContext('fails if missing Begin PBXBuildFile section', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(<String>[]),
                ),
              );
              expect(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find beginning of PBXBuildFile section'),
              );
            });

            testWithoutContext('fails if missing End PBXBuildFile section', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_buildFileSectionIndex] = '''
/* Begin PBXBuildFile section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_buildFileSectionIndex] = unmigratedBuildFileSectionAsJson;

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(<String>[]),
                ),
              );
              expect(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find end of PBXBuildFile section'),
              );
            });

            testWithoutContext('fails if End before Begin for PBXBuildFile section', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_buildFileSectionIndex] = '''
/* End PBXBuildFile section */
/* Begin PBXBuildFile section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_buildFileSectionIndex] = unmigratedBuildFileSectionAsJson;

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(<String>[]),
                ),
              );
              expect(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Found the end of PBXBuildFile section before the beginning.'),
              );
            });

            testWithoutContext('successfully added', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_buildFileSectionIndex] = unmigratedBuildFileSection;
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_buildFileSectionIndex] = unmigratedBuildFileSectionAsJson;

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXBuildFile already migrated. Skipping...'),
                isFalse,
              );
              settingsBeforeMigration[_buildFileSectionIndex] = migratedBuildFileSection;
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(settingsBeforeMigration),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });
          });

          group('migrate PBXFrameworksBuildPhase', () {
            testWithoutContext('fails if missing PBXFrameworksBuildPhase section', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration.removeAt(_frameworksBuildPhaseSectionIndex);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_frameworksBuildPhaseSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find beginning of PBXFrameworksBuildPhase section'),
              );
            });

            testWithoutContext('fails if missing Runner target subsection following PBXFrameworksBuildPhase begin header', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_frameworksBuildPhaseSectionIndex] = '''
/* Begin PBXFrameworksBuildPhase section */
/* End PBXFrameworksBuildPhase section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_frameworksBuildPhaseSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find PBXFrameworksBuildPhase for Runner target'),
              );
            });

            testWithoutContext('fails if missing Runner target subsection before PBXFrameworksBuildPhase end header', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_frameworksBuildPhaseSectionIndex] = '''
/* Begin PBXFrameworksBuildPhase section */
/* End PBXFrameworksBuildPhase section */
/* Begin NonExistant section */
    ${_runnerFrameworksBuildPhaseIdentifer(platform)} /* Frameworks */ = {
    };
/* End NonExistant section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_frameworksBuildPhaseSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find PBXFrameworksBuildPhase for Runner target'),
              );
            });

            testWithoutContext('fails if missing Runner target in parsed settings', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_frameworksBuildPhaseSectionIndex] = unmigratedFrameworksBuildPhaseSection(platform);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_frameworksBuildPhaseSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find parsed PBXFrameworksBuildPhase for Runner target'),
              );
            });

            testWithoutContext('successfully added when files field is missing', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_frameworksBuildPhaseSectionIndex] = unmigratedFrameworksBuildPhaseSection(
                platform,
                missingFiles: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_frameworksBuildPhaseSectionIndex] = unmigratedFrameworksBuildPhaseSectionAsJson(
                platform,
                missingFiles: true,
              );
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_frameworksBuildPhaseSectionIndex] = migratedFrameworksBuildPhaseSection(
                platform,
                missingFiles: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXFrameworksBuildPhase already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when files field is empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXFrameworksBuildPhase already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(_allSectionsMigrated(platform)),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when files field is not empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_frameworksBuildPhaseSectionIndex] = unmigratedFrameworksBuildPhaseSection(
                platform,
                withCocoapods: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_frameworksBuildPhaseSectionIndex] = unmigratedFrameworksBuildPhaseSectionAsJson(
                platform,
                withCocoapods: true,
              );
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_frameworksBuildPhaseSectionIndex] = migratedFrameworksBuildPhaseSection(
                platform,
                withCocoapods: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXFrameworksBuildPhase already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });
          });

          group('migrate PBXNativeTarget', () {
            testWithoutContext('fails if missing PBXNativeTarget section', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration.removeAt(_nativeTargetSectionIndex);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_nativeTargetSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find beginning of PBXNativeTarget section'),
              );
            });

            testWithoutContext('fails if missing Runner target in parsed settings', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_nativeTargetSectionIndex] = unmigratedNativeTargetSection(platform);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_nativeTargetSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find parsed PBXNativeTarget for Runner target'),
              );
            });

            testWithoutContext('fails if missing Runner target subsection following PBXNativeTarget begin header', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_nativeTargetSectionIndex] = '''
/* Begin PBXNativeTarget section */
/* End PBXNativeTarget section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find PBXNativeTarget for Runner target'),
              );
            });

            testWithoutContext('fails if missing Runner target subsection before PBXNativeTarget end header', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_nativeTargetSectionIndex] = '''
/* Begin PBXNativeTarget section */
/* End PBXNativeTarget section */
/* Begin NonExistant section */
    ${_runnerNativeTargetIdentifer(platform)} /* Runner */ = {
    };
/* End NonExistant section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find PBXNativeTarget for Runner target'),
              );
            });

            testWithoutContext('successfully added when packageProductDependencies field is missing', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_nativeTargetSectionIndex] = unmigratedNativeTargetSection(
                platform,
                missingPackageProductDependencies: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_nativeTargetSectionIndex] = unmigratedNativeTargetSectionAsJson(
                platform,
                missingPackageProductDependencies: true,
              );
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_nativeTargetSectionIndex] = migratedNativeTargetSection(
                platform,
                missingPackageProductDependencies: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXNativeTarget already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when packageProductDependencies field is empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_nativeTargetSectionIndex] = unmigratedNativeTargetSection(platform);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXNativeTarget already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(_allSectionsMigrated(platform)),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when packageProductDependencies field is not empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_nativeTargetSectionIndex] = unmigratedNativeTargetSection(
                platform,
                withOtherDependency: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_nativeTargetSectionIndex] = migratedNativeTargetSection(
                platform,
                withOtherDependency: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXNativeTarget already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });
          });

          group('migrate PBXProject', () {
            testWithoutContext('fails if missing PBXProject section', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration.removeAt(_projectSectionIndex);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_projectSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find beginning of PBXProject section'),
              );
            });

            testWithoutContext('fails if missing Runner project subsection following PBXProject begin header', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_projectSectionIndex] = '''
/* Begin PBXProject section */
/* End PBXProject section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );

              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_projectSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find PBXProject for Runner'),
              );
            });

            testWithoutContext('fails if missing Runner project subsection before PBXProject end header', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_projectSectionIndex] = '''
/* Begin PBXProject section */
/* End PBXProject section */
/* Begin NonExistant section */
    ${_projectIdentifier(platform)} /* Project object */ = {
    };
/* End NonExistant section */
''';
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );

              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_projectSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find PBXProject for Runner'),
              );
            });

            testWithoutContext('fails if missing Runner project in parsed settings', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_projectSectionIndex] = unmigratedProjectSection(platform);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_projectSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find parsed PBXProject for Runner'),
              );
            });

            testWithoutContext('successfully added when packageReferences field is missing', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_projectSectionIndex] = unmigratedProjectSection(
                platform,
                missingPackageReferences: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );

              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration[_projectSectionIndex] = unmigratedProjectSectionAsJson(
                platform,
                missingPackageReferences: true,
              );

              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_projectSectionIndex] = migratedProjectSection(
                platform,
                missingPackageReferences: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXProject already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when packageReferences field is empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_projectSectionIndex] = unmigratedProjectSection(platform);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXProject already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(_allSectionsMigrated(platform)),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when packageReferences field is not empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_projectSectionIndex] = unmigratedProjectSection(
                platform,
                withOtherReference: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_projectSectionIndex] = migratedProjectSection(
                platform,
                withOtherReference: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('PBXProject already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });
          });

          group('migrate XCLocalSwiftPackageReference', () {
            testWithoutContext('fails if unable to find section to append it after', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_localSwiftPackageReferenceSectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find any sections'),
              );
            });

            testWithoutContext('successfully added when section is missing', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration.removeAt(_localSwiftPackageReferenceSectionIndex);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings.removeAt(_localSwiftPackageReferenceSectionIndex);
              expectedSettings.add(migratedLocalSwiftPackageReferenceSection());

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('XCLocalSwiftPackageReference already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when section is empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_localSwiftPackageReferenceSectionIndex] = unmigratedLocalSwiftPackageReferenceSection();
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('XCLocalSwiftPackageReference already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(_allSectionsMigrated(platform)),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when section is not empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_localSwiftPackageReferenceSectionIndex] = unmigratedLocalSwiftPackageReferenceSection(
                withOtherReference: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_localSwiftPackageReferenceSectionIndex] = migratedLocalSwiftPackageReferenceSection(
                withOtherReference: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('XCLocalSwiftPackageReference already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });
          });

          group('migrate XCSwiftPackageProductDependency', () {
            testWithoutContext('fails if unable to find section to append it after', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsMigratedAsJson(platform),
              ];
              settingsAsJsonBeforeMigration.removeAt(_swiftPackageProductDependencySectionIndex);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: FakePlistParser(
                  json: _plutilOutput(settingsAsJsonBeforeMigration),
                ),
              );
              await expectLater(
                () => projectMigration.migrate(),
                throwsToolExit(message: 'Unable to find any sections'),
              );
            });

            testWithoutContext('successfully added when section is missing', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration.removeAt(_swiftPackageProductDependencySectionIndex);
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('XCSwiftPackageProductDependency already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(_allSectionsMigrated(platform)),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when section is empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_swiftPackageProductDependencySectionIndex] = unmigratedSwiftPackageProductDependencySection();
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('XCSwiftPackageProductDependency already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(_allSectionsMigrated(platform)),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });

            testWithoutContext('successfully added when section is not empty', () async {
              final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
              final BufferLogger testLogger = BufferLogger.test();
              final FakeXcodeProject project = FakeXcodeProject(
                platform: platform.name,
                fileSystem: memoryFileSystem,
                logger: testLogger,
              );
              _createProjectFiles(project, platform);

              final List<String> settingsBeforeMigration = <String>[
                ..._allSectionsUnmigrated(platform),
              ];
              settingsBeforeMigration[_swiftPackageProductDependencySectionIndex] = unmigratedSwiftPackageProductDependencySection(
                withOtherDependency: true,
              );
              project.xcodeProjectInfoFile.writeAsStringSync(
                _projectSettings(settingsBeforeMigration),
              );
              final List<String> settingsAsJsonBeforeMigration = <String>[
                ..._allSectionsUnmigratedAsJson(platform),
              ];
              final List<String> expectedSettings = <String>[
                ..._allSectionsMigrated(platform),
              ];
              expectedSettings[_swiftPackageProductDependencySectionIndex] = migratedSwiftPackageProductDependencySection(
                withOtherDependency: true,
              );

              final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
                _plutilOutput(settingsAsJsonBeforeMigration),
                _plutilOutput(_allSectionsMigratedAsJson(platform)),
              ]);

              final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
                project,
                platform,
                BuildInfo.debug,
                xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
                logger: testLogger,
                fileSystem: memoryFileSystem,
                plistParser: plistParser,
              );
              await projectMigration.migrate();
              expect(testLogger.errorText, isEmpty);
              expect(
                testLogger.traceText.contains('XCSwiftPackageProductDependency already migrated. Skipping...'),
                isFalse,
              );
              expect(
                project.xcodeProjectInfoFile.readAsStringSync(),
                _projectSettings(expectedSettings),
              );
              expect(plistParser.hasRemainingExpectations, isFalse);
            });
          });

          testWithoutContext('throw if settings not updated correctly', () async{
            final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
            final BufferLogger testLogger = BufferLogger.test();
            final FakeXcodeProject project = FakeXcodeProject(
              platform: platform.name,
              fileSystem: memoryFileSystem,
              logger: testLogger,
            );
            _createProjectFiles(project, platform);
            project.xcodeProjectInfoFile.writeAsStringSync(
              _projectSettings(_allSectionsUnmigrated(platform)),
            );

            final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
              _plutilOutput(_allSectionsUnmigratedAsJson(platform)),
              _plutilOutput(_allSectionsUnmigratedAsJson(platform)),
            ]);

            final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
              project,
              platform,
              BuildInfo.debug,
              xcodeProjectInterpreter: FakeXcodeProjectInterpreter(),
              logger: testLogger,
              fileSystem: memoryFileSystem,
              plistParser: plistParser,
            );
            await expectLater(
              () => projectMigration.migrate(),
              throwsToolExit(message: 'Settings were not updated correctly.'),
            );
            expect(
              testLogger.errorText,
              contains('PBXBuildFile was not migrated or was migrated incorrectly.'),
            );
            expect(
              testLogger.errorText,
              contains('PBXFrameworksBuildPhase was not migrated or was migrated incorrectly.'),
            );
            expect(
              testLogger.errorText,
              contains('PBXNativeTarget was not migrated or was migrated incorrectly.'),
            );
            expect(
              testLogger.errorText,
              contains('PBXProject was not migrated or was migrated incorrectly.'),
            );
            expect(
              testLogger.errorText,
              contains('XCLocalSwiftPackageReference was not migrated or was migrated incorrectly.'),
            );
            expect(
              testLogger.errorText,
              contains('XCSwiftPackageProductDependency was not migrated or was migrated incorrectly.'),
            );
          });
        });
      }
    });

    group('validate project settings', () {
      testWithoutContext('throw if settings fail to compile', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        const SupportedPlatform platform = SupportedPlatform.ios;
        final FakeXcodeProject project = FakeXcodeProject(
          platform: platform.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, platform);
        project.xcodeProjectInfoFile.writeAsStringSync(
          _projectSettings(_allSectionsUnmigrated(platform)),
        );

        final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
          _plutilOutput(_allSectionsUnmigratedAsJson(platform)),
          _plutilOutput(_allSectionsMigratedAsJson(platform)),
        ]);

        final SwiftPackageManagerIntegrationMigration projectMigration = SwiftPackageManagerIntegrationMigration(
          project,
          platform,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(
            throwErrorOnGetInfo: true,
          ),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: plistParser,
        );
        await expectLater(
          () => projectMigration.migrate(),
          throwsToolExit(message: 'Unable to get Xcode project information'),
        );
      });

      testWithoutContext('restore project settings from backup on failure', () async {
        final MemoryFileSystem memoryFileSystem = MemoryFileSystem();
        final BufferLogger testLogger = BufferLogger.test();
        const SupportedPlatform platform = SupportedPlatform.ios;
        final FakeXcodeProject project = FakeXcodeProject(
          platform: platform.name,
          fileSystem: memoryFileSystem,
          logger: testLogger,
        );
        _createProjectFiles(project, platform);

        final String originalProjectInfo = _projectSettings(
          _allSectionsUnmigrated(platform),
        );
        project.xcodeProjectInfoFile.writeAsStringSync(originalProjectInfo);
        final String originalSchemeContents = _validBuildActions(platform);

        final FakePlistParser plistParser = FakePlistParser.multiple(<String>[
          _plutilOutput(_allSectionsUnmigratedAsJson(platform)),
          _plutilOutput(_allSectionsMigratedAsJson(platform)),
        ]);

        final FakeSwiftPackageManagerIntegrationMigration projectMigration = FakeSwiftPackageManagerIntegrationMigration(
          project,
          platform,
          BuildInfo.debug,
          xcodeProjectInterpreter: FakeXcodeProjectInterpreter(
            throwErrorOnGetInfo: true,
          ),
          logger: testLogger,
          fileSystem: memoryFileSystem,
          plistParser: plistParser,
          validateBackup: true,
        );
        await expectLater(
          () async => projectMigration.migrate(),
          throwsToolExit(),
        );
        expect(
          testLogger.traceText,
          contains('Restoring project settings from backup file...'),
        );
        expect(
          project.xcodeProjectInfoFile.readAsStringSync(),
          originalProjectInfo,
        );
        expect(
          project.xcodeProjectSchemeFile().readAsStringSync(),
          originalSchemeContents,
        );
      });
    });
  });
}

void _createProjectFiles(
  FakeXcodeProject project,
  SupportedPlatform platform, {
  bool createSchemeFile = true,
  String? scheme,
}) {
  project.parent.directory.createSync(recursive: true);
  project.hostAppRoot.createSync(recursive: true);
  project.xcodeProjectInfoFile.createSync(recursive: true);
  if (createSchemeFile) {
    project.xcodeProjectSchemeFile(scheme: scheme).createSync(recursive: true);
    project.xcodeProjectSchemeFile().writeAsStringSync(
      _validBuildActions(platform),
    );
  }
}

String _validBuildActions(
  SupportedPlatform platform, {
  bool hasPreActions = false,
  bool hasFrameworkScript = false,
}) {
  final String scriptText;
  if (platform == SupportedPlatform.ios) {
    scriptText = r'scriptText = "/bin/sh &quot;$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh&quot; prepare&#10;">';
  } else {
    scriptText = r'scriptText = "&quot;$FLUTTER_ROOT&quot;/packages/flutter_tools/bin/macos_assemble.sh prepare&#10;">';
  }
  String preActions = '';
  if (hasFrameworkScript) {
    preActions = '''
\n      <PreActions>
         <ExecutionAction
            ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
            <ActionContent
               title = "Run Prepare Flutter Framework Script"
               $scriptText
               <EnvironmentBuildable>
                  <BuildableReference
                     BuildableIdentifier = "primary"
                     BlueprintIdentifier = "${_runnerNativeTargetIdentifer(platform)}"
                     BuildableName = "Runner.app"
                     BlueprintName = "Runner"
                     ReferencedContainer = "container:Runner.xcodeproj">
                  </BuildableReference>
               </EnvironmentBuildable>
            </ActionContent>
         </ExecutionAction>
      </PreActions>''';
  } else if (hasPreActions) {
    preActions = '''
\n      <PreActions>
      </PreActions>''';
  }
  return '''
   <BuildAction
      parallelizeBuildables = "YES"
      buildImplicitDependencies = "YES">$preActions
      <BuildActionEntries>
         <BuildActionEntry
            buildForTesting = "YES"
            buildForRunning = "YES"
            buildForProfiling = "YES"
            buildForArchiving = "YES"
            buildForAnalyzing = "YES">
${_validBuildableReference(platform)}
         </BuildActionEntry>
      </BuildActionEntries>
   </BuildAction>
''';
}

String _validBuildableReference(SupportedPlatform platform) {
  return '''
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "${_runnerNativeTargetIdentifer(platform)}"
               BuildableName = "Runner.app"
               BlueprintName = "Runner"
               ReferencedContainer = "container:Runner.xcodeproj">
            </BuildableReference>''';
}

const int _buildFileSectionIndex = 0;
const int _frameworksBuildPhaseSectionIndex = 1;
const int _nativeTargetSectionIndex = 2;
const int _projectSectionIndex = 3;
const int _localSwiftPackageReferenceSectionIndex = 4;
const int _swiftPackageProductDependencySectionIndex = 5;

List<String> _allSectionsMigrated(SupportedPlatform platform) {
  return <String>[
    migratedBuildFileSection,
    migratedFrameworksBuildPhaseSection(platform),
    migratedNativeTargetSection(platform),
    migratedProjectSection(platform),
    migratedLocalSwiftPackageReferenceSection(),
    migratedSwiftPackageProductDependencySection(),
  ];
}

List<String> _allSectionsMigratedAsJson(SupportedPlatform platform) {
  return <String>[
    migratedBuildFileSectionAsJson,
    migratedFrameworksBuildPhaseSectionAsJson(platform),
    migratedNativeTargetSectionAsJson(platform),
    migratedProjectSectionAsJson(platform),
    migratedLocalSwiftPackageReferenceSectionAsJson,
    migratedSwiftPackageProductDependencySectionAsJson,
  ];
}

List<String> _allSectionsUnmigrated(SupportedPlatform platform) {
  return <String>[
    unmigratedBuildFileSection,
    unmigratedFrameworksBuildPhaseSection(platform),
    unmigratedNativeTargetSection(platform),
    unmigratedProjectSection(platform),
    unmigratedLocalSwiftPackageReferenceSection(),
    unmigratedSwiftPackageProductDependencySection(),
  ];
}

List<String> _allSectionsUnmigratedAsJson(SupportedPlatform platform) {
  return <String>[
    unmigratedBuildFileSectionAsJson,
    unmigratedFrameworksBuildPhaseSectionAsJson(platform),
    unmigratedNativeTargetSectionAsJson(platform),
    unmigratedProjectSectionAsJson(platform),
  ];
}

String _plutilOutput(List<String> objects) {
  return '''
{
  "archiveVersion" : "1",
  "classes" : {

  },
  "objects" : {
${objects.join(',\n')}
  }
}
''';
}

String _projectSettings(List<String> objects) {
  return '''
${objects.join('\n')}
''';
}

String _runnerFrameworksBuildPhaseIdentifer(SupportedPlatform platform) {
  return platform == SupportedPlatform.ios
      ? '97C146EB1CF9000F007C117D'
      : '33CC10EA2044A3C60003C045';
}

String _runnerNativeTargetIdentifer(SupportedPlatform platform) {
  return platform == SupportedPlatform.ios
      ? '97C146ED1CF9000F007C117D'
      : '33CC10EC2044A3C60003C045';
}

String _projectIdentifier(SupportedPlatform platform) {
  return platform == SupportedPlatform.ios
      ? '97C146E61CF9000F007C117D'
      : '33CC10E52044A3C60003C045';
}

// PBXBuildFile
const String unmigratedBuildFileSection = '''
/* Begin PBXBuildFile section */
		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
/* End PBXBuildFile section */
''';
const String migratedBuildFileSection = '''
/* Begin PBXBuildFile section */
		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
		78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
/* End PBXBuildFile section */
''';
const String unmigratedBuildFileSectionAsJson = '''
    "97C146FC1CF9000F007C117D" : {
      "fileRef" : "97C146FA1CF9000F007C117D",
      "isa" : "PBXBuildFile"
    },
    "74858FAF1ED2DC5600515810" : {
      "fileRef" : "74858FAE1ED2DC5600515810",
      "isa" : "PBXBuildFile"
    }''';
const String migratedBuildFileSectionAsJson = '''
    "78A318202AECB46A00862997" : {
      "isa" : "PBXBuildFile",
      "productRef" : "78A3181F2AECB46A00862997"
    },
    "97C146FC1CF9000F007C117D" : {
      "fileRef" : "97C146FA1CF9000F007C117D",
      "isa" : "PBXBuildFile"
    },
    "74858FAF1ED2DC5600515810" : {
      "fileRef" : "74858FAE1ED2DC5600515810",
      "isa" : "PBXBuildFile"
    }''';

// PBXFrameworksBuildPhase
String unmigratedFrameworksBuildPhaseSection(
  SupportedPlatform platform, {
  bool withCocoapods = false,
  bool missingFiles = false,
}) {
  return <String>[
    '/* Begin PBXFrameworksBuildPhase section */',
    '		${_runnerFrameworksBuildPhaseIdentifer(platform)} /* Frameworks */ = {',
    '			isa = PBXFrameworksBuildPhase;',
    '			buildActionMask = 2147483647;',
    if (!missingFiles) ...<String>[
      '			files = (',
      if (withCocoapods)
        '				FD5BB45FB410D26C457F3823 /* Pods_Runner.framework in Frameworks */,',
      '			);',
    ],
    '			runOnlyForDeploymentPostprocessing = 0;',
    '		};',
    '/* End PBXFrameworksBuildPhase section */',
  ].join('\n');
}

String migratedFrameworksBuildPhaseSection(
  SupportedPlatform platform, {
  bool withCocoapods = false,
  bool missingFiles = false,
}) {
  final List<String> filesField = <String>[
    '			files = (',
    '				78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,',
    if (withCocoapods)
      '				FD5BB45FB410D26C457F3823 /* Pods_Runner.framework in Frameworks */,',
    '			);',
  ];
  return <String>[
    '/* Begin PBXFrameworksBuildPhase section */',
    '		${_runnerFrameworksBuildPhaseIdentifer(platform)} /* Frameworks */ = {',
    if (missingFiles) ...filesField,
    '			isa = PBXFrameworksBuildPhase;',
    '			buildActionMask = 2147483647;',
    if (!missingFiles) ...filesField,
    '			runOnlyForDeploymentPostprocessing = 0;',
    '		};',
    '/* End PBXFrameworksBuildPhase section */',
  ].join('\n');
}

String unmigratedFrameworksBuildPhaseSectionAsJson(
  SupportedPlatform platform, {
  bool withCocoapods = false,
  bool missingFiles = false,
}) {
  return <String>[
    '    "${_runnerFrameworksBuildPhaseIdentifer(platform)}" : {',
    '      "buildActionMask" : "2147483647",',
    if (!missingFiles) ...<String>[
      '      "files" : [',
      if (withCocoapods) '        "FD5BB45FB410D26C457F3823"',
      '      ],',
    ],
    '      "isa" : "PBXFrameworksBuildPhase",',
    '      "runOnlyForDeploymentPostprocessing" : "0"',
    '    }',
  ].join('\n');
}

String migratedFrameworksBuildPhaseSectionAsJson(SupportedPlatform platform) {
  return '''
    "${_runnerFrameworksBuildPhaseIdentifer(platform)}" : {
      "buildActionMask" : "2147483647",
      "files" : [
        "78A318202AECB46A00862997"
      ],
      "isa" : "PBXFrameworksBuildPhase",
      "runOnlyForDeploymentPostprocessing" : "0"
    }''';
}

// PBXNativeTarget
String unmigratedNativeTargetSection(
  SupportedPlatform platform, {
  bool missingPackageProductDependencies = false,
  bool withOtherDependency = false,
}) {
  return <String>[
    '/* Begin PBXNativeTarget section */',
    '		${_runnerNativeTargetIdentifer(platform)} /* Runner */ = {',
    '			isa = PBXNativeTarget;',
    '			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;',
    '			buildPhases = (',
    '				9740EEB61CF901F6004384FC /* Run Script */,',
    '				97C146EA1CF9000F007C117D /* Sources */,',
    '				${_runnerFrameworksBuildPhaseIdentifer(platform)} /* Frameworks */,',
    '				97C146EC1CF9000F007C117D /* Resources */,',
    '				9705A1C41CF9048500538489 /* Embed Frameworks */,',
    '				3B06AD1E1E4923F5004D2608 /* Thin Binary */,',
    '			);',
    '			buildRules = (',
    '			);',
    '			dependencies = (',
    '			);',
    '			name = Runner;',
    if (!missingPackageProductDependencies) ...<String>[
      '			packageProductDependencies = (',
      if (withOtherDependency)
        '				010101010101010101010101 /* SomeOtherPackage */,',
      '			);',
    ],
    '			productName = Runner;',
    '			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;',
    '			productType = "com.apple.product-type.application";',
    '		};',
    '/* End PBXNativeTarget section */',
  ].join('\n');
}

String migratedNativeTargetSection(
  SupportedPlatform platform, {
  bool missingPackageProductDependencies = false,
  bool withOtherDependency = false,
}) {
  final List<String> packageDependencies = <String>[
    '			packageProductDependencies = (',
    '				78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,',
    if (withOtherDependency)
      '				010101010101010101010101 /* SomeOtherPackage */,',
    '			);',
  ];
  return <String>[
    '/* Begin PBXNativeTarget section */',
    '		${_runnerNativeTargetIdentifer(platform)} /* Runner */ = {',
    if (missingPackageProductDependencies) ...packageDependencies,
    '			isa = PBXNativeTarget;',
    '			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;',
    '			buildPhases = (',
    '				9740EEB61CF901F6004384FC /* Run Script */,',
    '				97C146EA1CF9000F007C117D /* Sources */,',
    '				${_runnerFrameworksBuildPhaseIdentifer(platform)} /* Frameworks */,',
    '				97C146EC1CF9000F007C117D /* Resources */,',
    '				9705A1C41CF9048500538489 /* Embed Frameworks */,',
    '				3B06AD1E1E4923F5004D2608 /* Thin Binary */,',
    '			);',
    '			buildRules = (',
    '			);',
    '			dependencies = (',
    '			);',
    '			name = Runner;',
    if (!missingPackageProductDependencies) ...packageDependencies,
    '			productName = Runner;',
    '			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;',
    '			productType = "com.apple.product-type.application";',
    '		};',
    '/* End PBXNativeTarget section */',
  ].join('\n');
}

String unmigratedNativeTargetSectionAsJson(
  SupportedPlatform platform, {
  bool missingPackageProductDependencies = false,
}) {
  return <String>[
    '    "${_runnerNativeTargetIdentifer(platform)}" : {',
    '      "buildConfigurationList" : "97C147051CF9000F007C117D",',
    '      "buildPhases" : [',
    '        "9740EEB61CF901F6004384FC",',
    '        "97C146EA1CF9000F007C117D",',
    '        "${_runnerFrameworksBuildPhaseIdentifer(platform)}",',
    '        "97C146EC1CF9000F007C117D",',
    '        "9705A1C41CF9048500538489",',
    '        "3B06AD1E1E4923F5004D2608"',
    '      ],',
    '      "buildRules" : [',
    '      ],',
    '      "dependencies" : [',
    '      ],',
    '      "isa" : "PBXNativeTarget",',
    '      "name" : "Runner",',
    if (!missingPackageProductDependencies) ...<String>[
      '      "packageProductDependencies" : [',
      '      ],',
    ],
    '      "productName" : "Runner",',
    '      "productReference" : "97C146EE1CF9000F007C117D",',
    '      "productType" : "com.apple.product-type.application"',
    '    }',
  ].join('\n');
}

String migratedNativeTargetSectionAsJson(SupportedPlatform platform) {
  return '''
    "${_runnerNativeTargetIdentifer(platform)}" : {
      "buildConfigurationList" : "97C147051CF9000F007C117D",
      "buildPhases" : [
        "9740EEB61CF901F6004384FC",
        "97C146EA1CF9000F007C117D",
        "${_runnerFrameworksBuildPhaseIdentifer(platform)}",
        "97C146EC1CF9000F007C117D",
        "9705A1C41CF9048500538489",
        "3B06AD1E1E4923F5004D2608"
      ],
      "buildRules" : [

      ],
      "dependencies" : [

      ],
      "isa" : "PBXNativeTarget",
      "name" : "Runner",
      "packageProductDependencies" : [
        "78A3181F2AECB46A00862997"
      ],
      "productName" : "Runner",
      "productReference" : "97C146EE1CF9000F007C117D",
      "productType" : "com.apple.product-type.application"
    }''';
}

// PBXProject
String unmigratedProjectSection(
  SupportedPlatform platform, {
  bool missingPackageReferences = false,
  bool withOtherReference = false,
}) {
  return <String>[
    '/* Begin PBXProject section */',
    '		${_projectIdentifier(platform)} /* Project object */ = {',
    '			isa = PBXProject;',
    '			attributes = {',
    '				BuildIndependentTargetsInParallel = YES;',
    '				LastUpgradeCheck = 1510;',
    '				ORGANIZATIONNAME = "";',
    '				TargetAttributes = {',
    '					331C8080294A63A400263BE5 = {',
    '						CreatedOnToolsVersion = 14.0;',
    '						TestTargetID = ${_runnerNativeTargetIdentifer(platform)};',
    '					};',
    '					${_runnerNativeTargetIdentifer(platform)} = {',
    '						CreatedOnToolsVersion = 7.3.1;',
    '						LastSwiftMigration = 1100;',
    '					};',
    '				};',
    '			};',
    '			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;',
    '			compatibilityVersion = "Xcode 9.3";',
    '			developmentRegion = en;',
    '			hasScannedForEncodings = 0;',
    '			knownRegions = (',
    '				en,',
    '				Base,',
    '			);',
    '			mainGroup = 97C146E51CF9000F007C117D;',
    if (!missingPackageReferences) ...<String>[
      '			packageReferences = (',
      if (withOtherReference)
        '				010101010101010101010101 /* XCLocalSwiftPackageReference "SomeOtherPackage" */,',
      '			);',
    ],
    '			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;',
    '			projectDirPath = "";',
    '			projectRoot = "";',
    '			targets = (',
    '				${_runnerNativeTargetIdentifer(platform)} /* Runner */,',
    '				331C8080294A63A400263BE5 /* RunnerTests */,',
    '			);',
    '		};',
    '/* End PBXProject section */',
  ].join('\n');
}

String migratedProjectSection(
  SupportedPlatform platform, {
  bool missingPackageReferences = false,
  bool withOtherReference = false,
}) {
  final List<String> packageDependencies = <String>[
    '			packageReferences = (',
    '				781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,',
    if (withOtherReference)
      '				010101010101010101010101 /* XCLocalSwiftPackageReference "SomeOtherPackage" */,',
    '			);',
  ];
  return <String>[
    '/* Begin PBXProject section */',
    '		${_projectIdentifier(platform)} /* Project object */ = {',
    if (missingPackageReferences) ...packageDependencies,
    '			isa = PBXProject;',
    '			attributes = {',
    '				BuildIndependentTargetsInParallel = YES;',
    '				LastUpgradeCheck = 1510;',
    '				ORGANIZATIONNAME = "";',
    '				TargetAttributes = {',
    '					331C8080294A63A400263BE5 = {',
    '						CreatedOnToolsVersion = 14.0;',
    '						TestTargetID = ${_runnerNativeTargetIdentifer(platform)};',
    '					};',
    '					${_runnerNativeTargetIdentifer(platform)} = {',
    '						CreatedOnToolsVersion = 7.3.1;',
    '						LastSwiftMigration = 1100;',
    '					};',
    '				};',
    '			};',
    '			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;',
    '			compatibilityVersion = "Xcode 9.3";',
    '			developmentRegion = en;',
    '			hasScannedForEncodings = 0;',
    '			knownRegions = (',
    '				en,',
    '				Base,',
    '			);',
    '			mainGroup = 97C146E51CF9000F007C117D;',
    if (!missingPackageReferences) ...packageDependencies,
    '			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;',
    '			projectDirPath = "";',
    '			projectRoot = "";',
    '			targets = (',
    '				${_runnerNativeTargetIdentifer(platform)} /* Runner */,',
    '				331C8080294A63A400263BE5 /* RunnerTests */,',
    '			);',
    '		};',
    '/* End PBXProject section */',
  ].join('\n');
}

String unmigratedProjectSectionAsJson(
  SupportedPlatform platform, {
  bool missingPackageReferences = false,
}) {
  return <String>[
    '    "${_projectIdentifier(platform)}" : {',
    '      "attributes" : {',
    '        "BuildIndependentTargetsInParallel" : "YES",',
    '        "LastUpgradeCheck" : "1510",',
    '        "ORGANIZATIONNAME" : "",',
    '        "TargetAttributes" : {',
    '          "${_runnerNativeTargetIdentifer(platform)}" : {',
    '            "CreatedOnToolsVersion" : "7.3.1",',
    '            "LastSwiftMigration" : "1100"',
    '          },',
    '          "331C8080294A63A400263BE5" : {',
    '            "CreatedOnToolsVersion" : "14.0",',
    '            "TestTargetID" : "${_runnerNativeTargetIdentifer(platform)}"',
    '          }',
    '        }',
    '      },',
    '      "buildConfigurationList" : "97C146E91CF9000F007C117D",',
    '      "compatibilityVersion" : "Xcode 9.3",',
    '      "developmentRegion" : "en",',
    '      "hasScannedForEncodings" : "0",',
    '      "isa" : "PBXProject",',
    '      "knownRegions" : [',
    '        "en",',
    '        "Base"',
    '      ],',
    '      "mainGroup" : "97C146E51CF9000F007C117D",',
    if (!missingPackageReferences) ...<String>[
      '      "packageReferences" : [',
      '      ],',
    ],
    '      "productRefGroup" : "97C146EF1CF9000F007C117D",',
    '      "projectDirPath" : "",',
    '      "projectRoot" : "",',
    '      "targets" : [',
    '        "${_runnerNativeTargetIdentifer(platform)}",',
    '        "331C8080294A63A400263BE5"',
    '      ]',
    '    }',
  ].join('\n');
}

String migratedProjectSectionAsJson(SupportedPlatform platform) {
  return '''
    "${_projectIdentifier(platform)}" : {
      "attributes" : {
        "BuildIndependentTargetsInParallel" : "YES",
        "LastUpgradeCheck" : "1510",
        "ORGANIZATIONNAME" : "",
        "TargetAttributes" : {
          "${_runnerNativeTargetIdentifer(platform)}" : {
            "CreatedOnToolsVersion" : "7.3.1",
            "LastSwiftMigration" : "1100"
          },
          "331C8080294A63A400263BE5" : {
            "CreatedOnToolsVersion" : "14.0",
            "TestTargetID" : "${_runnerNativeTargetIdentifer(platform)}"
          }
        }
      },
      "buildConfigurationList" : "97C146E91CF9000F007C117D",
      "compatibilityVersion" : "Xcode 9.3",
      "developmentRegion" : "en",
      "hasScannedForEncodings" : "0",
      "isa" : "PBXProject",
      "knownRegions" : [
        "en",
        "Base"
      ],
      "mainGroup" : "97C146E51CF9000F007C117D",
      "packageReferences" : [
        "781AD8BC2B33823900A9FFBB"
      ],
      "productRefGroup" : "97C146EF1CF9000F007C117D",
      "projectDirPath" : "",
      "projectRoot" : "",
      "targets" : [
        "${_runnerNativeTargetIdentifer(platform)}",
        "331C8080294A63A400263BE5"
      ]
    }''';
}

// XCLocalSwiftPackageReference
String unmigratedLocalSwiftPackageReferenceSection({
  bool withOtherReference = false,
}) {
  return <String>[
    '/* Begin XCLocalSwiftPackageReference section */',
    if (withOtherReference) ...<String>[
      '		010101010101010101010101 /* XCLocalSwiftPackageReference "SomeOtherPackage" */ = {',
      '			isa = XCLocalSwiftPackageReference;',
      '			relativePath = SomeOtherPackage;',
      '		};',
    ],
    '/* End XCLocalSwiftPackageReference section */',
  ].join('\n');
}

String migratedLocalSwiftPackageReferenceSection({
  bool withOtherReference = false,
}) {
  return <String>[
    '/* Begin XCLocalSwiftPackageReference section */',
    if (withOtherReference) ...<String>[
      '		010101010101010101010101 /* XCLocalSwiftPackageReference "SomeOtherPackage" */ = {',
      '			isa = XCLocalSwiftPackageReference;',
      '			relativePath = SomeOtherPackage;',
      '		};',
    ],
    '		781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {',
    '			isa = XCLocalSwiftPackageReference;',
    '			relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;',
    '		};',
    '/* End XCLocalSwiftPackageReference section */',
  ].join('\n');
}

const String migratedLocalSwiftPackageReferenceSectionAsJson = '''
    "781AD8BC2B33823900A9FFBB" : {
      "isa" : "XCLocalSwiftPackageReference",
      "relativePath" : "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage"
    }''';

// XCSwiftPackageProductDependency
String unmigratedSwiftPackageProductDependencySection({
  bool withOtherDependency = false,
}) {
  return <String>[
    '/* Begin XCSwiftPackageProductDependency section */',
    if (withOtherDependency) ...<String>[
      '		010101010101010101010101 /* SomeOtherPackage */ = {',
      '			isa = XCSwiftPackageProductDependency;',
      '			productName = SomeOtherPackage;',
      '		};',
    ],
    '/* End XCSwiftPackageProductDependency section */',
  ].join('\n');
}

String migratedSwiftPackageProductDependencySection({
  bool withOtherDependency = false,
}) {
  return <String>[
    '/* Begin XCSwiftPackageProductDependency section */',
    if (withOtherDependency) ...<String>[
      '		010101010101010101010101 /* SomeOtherPackage */ = {',
      '			isa = XCSwiftPackageProductDependency;',
      '			productName = SomeOtherPackage;',
      '		};',
    ],
    '		78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {',
    '			isa = XCSwiftPackageProductDependency;',
    '			productName = FlutterGeneratedPluginSwiftPackage;',
    '		};',
    '/* End XCSwiftPackageProductDependency section */',
  ].join('\n');
}

const String migratedSwiftPackageProductDependencySectionAsJson = '''
    "78A3181F2AECB46A00862997" : {
      "isa" : "XCSwiftPackageProductDependency",
      "productName" : "FlutterGeneratedPluginSwiftPackage"
    }''';

class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterpreter {
  FakeXcodeProjectInterpreter({
    this.throwErrorOnGetInfo = false,
  });

  @override
  bool isInstalled = false;

  @override
  List<String> xcrunCommand() => <String>['xcrun'];

  final bool throwErrorOnGetInfo;

  @override
  Future<XcodeProjectInfo?> getInfo(String projectPath, {String? projectFilename}) async {
    if (throwErrorOnGetInfo) {
      throwToolExit('Unable to get Xcode project information');
    }
    return null;
  }
}

class FakePlistParser extends Fake implements PlistParser {
  FakePlistParser({
    String? json,
  }) : _outputPerCall = (json != null) ? <String>[json] : null;

  FakePlistParser.multiple(this._outputPerCall);

  final List<String>? _outputPerCall;

  @override
  String? plistJsonContent(String filePath) {
    if (_outputPerCall != null && _outputPerCall.isNotEmpty) {
      return _outputPerCall.removeAt(0);
    }
    return null;
  }

  bool get hasRemainingExpectations {
    return _outputPerCall != null && _outputPerCall.isNotEmpty;
  }
}

class FakeXcodeProject extends Fake implements IosProject {
  FakeXcodeProject({
    required MemoryFileSystem fileSystem,
    required String platform,
    required this.logger,
  }) : hostAppRoot = fileSystem.directory('app_name').childDirectory(platform),
  parent = FakeFlutterProject(fileSystem: fileSystem);

  final Logger logger;
  late XcodeProjectInfo? _projectInfo = XcodeProjectInfo(
    <String>['Runner'],
    <String>['Debug', 'Release', 'Profile'],
    <String>['Runner'],
    logger,
  );

  @override
  Directory hostAppRoot;

   @override
  FakeFlutterProject parent;

  @override
  Directory get xcodeProject => hostAppRoot.childDirectory('$hostAppProjectName.xcodeproj');

  @override
  File get xcodeProjectInfoFile => xcodeProject.childFile('project.pbxproj');

  @override
  late Directory? xcodeWorkspace = hostAppRoot.childDirectory('$hostAppProjectName.xcworkspace');

  @override
  String hostAppProjectName = 'Runner';

  @override
  Directory get flutterPluginSwiftPackageDirectory => hostAppRoot
      .childDirectory('Flutter')
      .childDirectory('ephemeral')
      .childDirectory('Packages')
      .childDirectory('FlutterGeneratedPluginSwiftPackage');

  @override
  File get flutterPluginSwiftPackageManifest =>
      flutterPluginSwiftPackageDirectory.childFile('Package.swift');

  @override
  bool get flutterPluginSwiftPackageInProjectSettings {
    return xcodeProjectInfoFile.existsSync() &&
        xcodeProjectInfoFile
            .readAsStringSync()
            .contains('FlutterGeneratedPluginSwiftPackage');
  }

  @override
  Future<XcodeProjectInfo?> projectInfo() async {
    return _projectInfo;
  }

  @override
  File xcodeProjectSchemeFile({String? scheme}) {
    final String schemeName = scheme ?? 'Runner';
    return xcodeProject.childDirectory('xcshareddata').childDirectory('xcschemes').childFile('$schemeName.xcscheme');
  }
}

class FakeFlutterProject extends Fake implements FlutterProject {
  FakeFlutterProject({
    required MemoryFileSystem fileSystem,
  }) : directory = fileSystem.directory('app_name');

  @override
  Directory directory;
}

class FakeSwiftPackageManagerIntegrationMigration extends SwiftPackageManagerIntegrationMigration {
  FakeSwiftPackageManagerIntegrationMigration(
    super.project,
    super.platform,
    super.buildInfo, {
    required super.xcodeProjectInterpreter,
    required super.logger,
    required super.fileSystem,
    required super.plistParser,
    this.validateBackup = false,
  }) : _xcodeProject = project;

  final XcodeBasedProject _xcodeProject;

  final bool validateBackup;
  @override
  void restoreFromBackup(SchemeInfo? schemeInfo) {
    if (validateBackup) {
      expect(backupProjectSettings.existsSync(), isTrue);
      final String originalSettings = backupProjectSettings.readAsStringSync();
      expect(
        _xcodeProject.xcodeProjectInfoFile.readAsStringSync() == originalSettings,
        isFalse,
      );

      expect(schemeInfo?.backupSchemeFile, isNotNull);
      final File backupScheme = schemeInfo!.backupSchemeFile!;
      expect(backupScheme.existsSync(), isTrue);
      final String originalScheme = backupScheme.readAsStringSync();
      expect(
        _xcodeProject.xcodeProjectSchemeFile().readAsStringSync() == originalScheme,
        isFalse,
      );

      super.restoreFromBackup(schemeInfo);
      expect(
        _xcodeProject.xcodeProjectInfoFile.readAsStringSync(),
        originalSettings,
      );
      expect(
        _xcodeProject.xcodeProjectSchemeFile().readAsStringSync(),
        originalScheme,
      );
    } else {
      super.restoreFromBackup(schemeInfo);
    }
  }
}
