// 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/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;

final String gradlew = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
final String gradlewExecutable = Platform.isWindows ? '.\\$gradlew' : './$gradlew';

/// Tests that the Android app containing a Flutter module can be built when
/// it has custom build types and flavors.
Future<void> main() async {
  await task(() async {

    section('Find Java');

    final String javaHome = await findJavaHome();
    if (javaHome == null) {
      return TaskResult.failure('Could not find Java');
    }

    print('\nUsing JAVA_HOME=$javaHome');

    section('Create Flutter module project');

    await flutter(
      'precache',
      options: <String>['--android', '--no-ios'],
    );

    final Directory tempDir = Directory.systemTemp.createTempSync('flutter_module_test.');
    final Directory projectDir = Directory(path.join(tempDir.path, 'hello'));
    try {
      await inDirectory(tempDir, () async {
        await flutter(
          'create',
          options: <String>['--org', 'io.flutter.devicelab', '--template=module', 'hello'],
        );
      });

      section('Run flutter pub get');

      await inDirectory(projectDir, () async {
        await flutter(
          'pub',
          options: <String>['get'],
        );
      });

      section('Add to existing Android app');

      final Directory hostAppDir = Directory(path.join(tempDir.path, 'hello_host_app_with_custom_build'));
      mkdir(hostAppDir);
      recursiveCopy(
        Directory(
          path.join(
            flutterDirectory.path,
            'dev',
            'integration_tests',
            'module_host_with_custom_build_v2_embedding',
          ),
        ),
        hostAppDir,
      );
      copy(
        File(path.join(projectDir.path, '.android', gradlew)),
        hostAppDir,
      );
      copy(
        File(path.join(projectDir.path, '.android', 'gradle', 'wrapper', 'gradle-wrapper.jar')),
        Directory(path.join(hostAppDir.path, 'gradle', 'wrapper')),
      );

      final Function clean = () async {
        section('Clean');
        await inDirectory(hostAppDir, () async {
          await exec(gradlewExecutable,
            <String>['clean'],
            environment: <String, String>{
              'JAVA_HOME': javaHome,
            },
          );
        });
      };

      if (!Platform.isWindows) {
        section('Make $gradlewExecutable executable');
        await inDirectory(hostAppDir, () async {
          await exec('chmod', <String>['+x', gradlewExecutable]);
        });
      }

      section('Build debug APKs');

      section('Run app:assembleDemoDebug');

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoDebug'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoDebugApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'debug',
        'app-demo-debug.apk',
      );

      if (!exists(File(demoDebugApk))) {
        return TaskResult.failure('Failed to build app-demo-debug.apk');
      }

      section('Verify snapshots in app-demo-debug.apk');

      checkCollectionContains<String>(<String>[
        ...flutterAssets,
        ...debugAssets,
      ], await getFilesInApk(demoDebugApk));

      await clean();

      // Change the order of the task and ensure that flutter_assets are in the APK.
      // https://github.com/flutter/flutter/pull/41333
      section('Run app:assembleDemoDebug - Merge assets before processing manifest');

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>[
            // Normally, `app:processDemoDebugManifest` runs before `app:mergeDemoDebugAssets`.
            // In this case, we run `app:mergeDemoDebugAssets` first.
            'app:mergeDemoDebugAssets',
            'app:processDemoDebugManifest',
            'app:assembleDemoDebug',
          ],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoDebugApk2 = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'debug',
        'app-demo-debug.apk',
      );

      if (!exists(File(demoDebugApk2))) {
        return TaskResult.failure('Failed to build app-demo-debug.apk');
      }

      section('Verify snapshots in app-demo-debug.apk');

      checkCollectionContains<String>(<String>[
        ...flutterAssets,
        ...debugAssets,
      ], await getFilesInApk(demoDebugApk2));

      await clean();

      section('Run app:assembleDemoStaging');

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoStaging'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoStagingApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'staging',
        'app-demo-staging.apk',
      );

      if (!exists(File(demoStagingApk))) {
        return TaskResult.failure('Failed to build app-demo-staging.apk');
      }

      section('Verify snapshots in app-demo-staging.apk');

      checkCollectionContains<String>(<String>[
        ...flutterAssets,
        ...debugAssets,
      ], await getFilesInApk(demoStagingApk));

      await clean();

      section('Build release APKs');

      section('Run app:assembleDemoRelease');

      await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoRelease'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoReleaseApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'release',
        'app-demo-release-unsigned.apk',
      );

      if (!exists(File(demoReleaseApk))) {
        return TaskResult.failure('Failed to build app-demo-release-unsigned.apk');
      }

      section('Verify AOT ELF in app-demo-release-unsigned.apk');

      checkCollectionContains<String>(<String>[
        ...flutterAssets,
        'lib/arm64-v8a/libflutter.so',
        'lib/arm64-v8a/libapp.so',
        'lib/armeabi-v7a/libflutter.so',
        'lib/armeabi-v7a/libapp.so',
      ], await getFilesInApk(demoReleaseApk));

      await clean();

      section('Run app:assembleDemoProd');

       await inDirectory(hostAppDir, () async {
        await exec(gradlewExecutable,
          <String>['app:assembleDemoProd'],
          environment: <String, String>{
            'JAVA_HOME': javaHome,
          },
        );
      });

      final String demoProdApk = path.join(
        hostAppDir.path,
        'app',
        'build',
        'outputs',
        'apk',
        'demo',
        'prod',
        'app-demo-prod-unsigned.apk',
      );

      if (!exists(File(demoProdApk))) {
        return TaskResult.failure('Failed to build app-demo-prod-unsigned.apk');
      }

      section('Verify AOT ELF in app-demo-prod-unsigned.apk');

      checkCollectionContains<String>(<String>[
        ...flutterAssets,
        'lib/arm64-v8a/libapp.so',
        'lib/arm64-v8a/libflutter.so',
        'lib/armeabi-v7a/libapp.so',
        'lib/armeabi-v7a/libflutter.so',
      ], await getFilesInApk(demoProdApk));

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