// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:flutter_devicelab/framework/apk_utils.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/ios.dart';
import 'package:flutter_devicelab/framework/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;

Future<void> main() async {
  await task(() async {
    try {
      await runProjectTest((FlutterProject flutterProject) async {
        section('Build app with with --obfuscate');
        await inDirectory(flutterProject.rootPath, () async {
          await flutter('build', options: <String>[
            'ios',
            '--release',
            '--obfuscate',
            '--split-debug-info=foo/',
            '--no-codesign',
          ]);
        });
        final String buildPath = path.join(
          flutterProject.rootPath,
          'build',
          'ios',
          'iphoneos',
        );
        final String outputAppPath = path.join(
          buildPath,
          'Runner.app',
        );
        final Directory outputAppFramework = Directory(path.join(
          outputAppPath,
          'Frameworks',
          'App.framework',
        ));

        final File outputAppFrameworkBinary = File(path.join(
          outputAppFramework.path,
          'App',
        ));

        if (!outputAppFrameworkBinary.existsSync()) {
          fail('Failed to produce expected output at ${outputAppFrameworkBinary.path}');
        }

        if (await dartObservatoryBonjourServiceFound(outputAppPath)) {
          throw TaskResult.failure('Release bundle has unexpected NSBonjourServices');
        }
        if (await localNetworkUsageFound(outputAppPath)) {
          throw TaskResult.failure('Release bundle has unexpected NSLocalNetworkUsageDescription');
        }

        section('Validate obfuscation');

        // Verify that an identifier from the Dart project code is not present
        // in the compiled binary.
        await inDirectory(flutterProject.rootPath, () async {
          final String response = await eval(
            'grep',
            <String>[flutterProject.name, outputAppFrameworkBinary.path],
            canFail: true,
          );
          if (response.trim().contains('matches')) {
            throw TaskResult.failure('Found project name in obfuscated dart library');
          }
        });

        section('Validate release contents');

        final Directory outputFlutterFramework = Directory(path.join(
          flutterProject.rootPath,
          outputAppPath,
          'Frameworks',
          'Flutter.framework',
        ));

        checkDirectoryNotExists(path.join(outputFlutterFramework.path, 'Headers'));
        checkDirectoryNotExists(path.join(outputFlutterFramework.path, 'Modules'));
        final File outputFlutterFrameworkBinary = File(path.join(
          outputFlutterFramework.path,
          'Flutter',
        ));

        if (!outputFlutterFrameworkBinary.existsSync()) {
          fail('Failed to produce expected output at ${outputFlutterFrameworkBinary.path}');
        }

        // Archiving should contain a bitcode blob, but not building in release.
        // This mimics Xcode behavior and present a developer from having to install a
        // 300+MB app to test devices.
        if (await containsBitcode(outputFlutterFrameworkBinary.path)) {
          throw TaskResult.failure('Bitcode present in Flutter.framework');
        }

        section('Xcode backend script');

        outputFlutterFramework.deleteSync(recursive: true);
        outputAppFramework.deleteSync(recursive: true);
        if (outputFlutterFramework.existsSync() || outputAppFramework.existsSync()) {
          fail('Failed to delete embedded frameworks');
        }

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

        // Simulate a common Xcode build setting misconfiguration
        // where FLUTTER_APPLICATION_PATH is missing
        final int result = await exec(
          xcodeBackendPath,
          <String>['embed_and_thin'],
          environment: <String, String>{
            'SOURCE_ROOT': flutterProject.iosPath,
            'BUILT_PRODUCTS_DIR': path.join(
              flutterProject.rootPath,
              'build',
              'ios',
              'Release-iphoneos',
            ),
            'TARGET_BUILD_DIR': buildPath,
            'FRAMEWORKS_FOLDER_PATH': 'Runner.app/Frameworks',
            'VERBOSE_SCRIPT_LOGGING': '1',
            'FLUTTER_BUILD_MODE': 'release',
            'ACTION': 'install', // Skip bitcode stripping since we just checked that above.
          },
        );

        if (result != 0) {
          fail('xcode_backend embed_and_thin failed');
        }

        if (!outputFlutterFrameworkBinary.existsSync()) {
          fail('Failed to re-embed ${outputFlutterFrameworkBinary.path}');
        }

        if (!outputAppFrameworkBinary.existsSync()) {
          fail('Failed to re-embed ${outputAppFrameworkBinary.path}');
        }

        section('Clean build');

        await inDirectory(flutterProject.rootPath, () async {
          await flutter('clean');
        });

        section('Validate debug contents');

        await inDirectory(flutterProject.rootPath, () async {
          await flutter('build', options: <String>[
            'ios',
            '--debug',
            '--no-codesign',
          ]);
        });

        // Debug should also not contain bitcode.
        if (await containsBitcode(outputFlutterFrameworkBinary.path)) {
          throw TaskResult.failure('Bitcode present in Flutter.framework');
        }

        if (!await dartObservatoryBonjourServiceFound(outputAppPath)) {
          throw TaskResult.failure('Debug bundle is missing NSBonjourServices');
        }
        if (!await localNetworkUsageFound(outputAppPath)) {
          throw TaskResult.failure('Debug bundle is missing NSLocalNetworkUsageDescription');
        }

        section('Clean build');

        await inDirectory(flutterProject.rootPath, () async {
          await flutter('clean');
        });

        section('Archive');

        await inDirectory(flutterProject.rootPath, () async {
          await flutter('build', options: <String>[
            'xcarchive',
          ]);
        });

        checkDirectoryExists(path.join(
          flutterProject.rootPath,
          'build',
          'ios',
          'archive',
          'Runner.xcarchive',
          'Products',
        ));
      });

      return TaskResult.success(null);
    } on TaskResult catch (taskResult) {
      return taskResult;
    } catch (e) {
      return TaskResult.failure(e.toString());
    }
  });
}
