// 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/memory.dart';
import 'package:flutter_tools/src/android/gradle_utils.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';

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

void main() {
   group('injectGradleWrapperIfNeeded', () {
    MemoryFileSystem memoryFileSystem;
    Directory tempDir;
    Directory gradleWrapperDirectory;

    setUp(() {
      memoryFileSystem = MemoryFileSystem.test();
      tempDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_artifacts_test.');
      gradleWrapperDirectory = memoryFileSystem.directory(
          memoryFileSystem.path.join(tempDir.path, 'bin', 'cache', 'artifacts', 'gradle_wrapper'));
      gradleWrapperDirectory.createSync(recursive: true);
      gradleWrapperDirectory
        .childFile('gradlew')
        .writeAsStringSync('irrelevant');
      gradleWrapperDirectory
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .createSync(recursive: true);
      gradleWrapperDirectory
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.jar')
        .writeAsStringSync('irrelevant');
    });

    testUsingContext('injects the wrapper when all files are missing', () {
      final Directory sampleAppAndroid = globals.fs.directory('/sample-app/android');
      sampleAppAndroid.createSync(recursive: true);

      gradleUtils.injectGradleWrapperIfNeeded(sampleAppAndroid);

      expect(sampleAppAndroid.childFile('gradlew').existsSync(), isTrue);

      expect(sampleAppAndroid
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.jar')
        .existsSync(), isTrue);

      expect(sampleAppAndroid
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.properties')
        .existsSync(), isTrue);

      expect(sampleAppAndroid
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.properties')
        .readAsStringSync(),
            'distributionBase=GRADLE_USER_HOME\n'
            'distributionPath=wrapper/dists\n'
            'zipStoreBase=GRADLE_USER_HOME\n'
            'zipStorePath=wrapper/dists\n'
            'distributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n');
    }, overrides: <Type, Generator>{
      Cache: () => Cache.test(rootOverride: tempDir, fileSystem: memoryFileSystem),
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingContext('injects the wrapper when some files are missing', () {
      final Directory sampleAppAndroid = globals.fs.directory('/sample-app/android');
      sampleAppAndroid.createSync(recursive: true);

      // There's an existing gradlew
      sampleAppAndroid.childFile('gradlew').writeAsStringSync('existing gradlew');

      gradleUtils.injectGradleWrapperIfNeeded(sampleAppAndroid);

      expect(sampleAppAndroid.childFile('gradlew').existsSync(), isTrue);
      expect(sampleAppAndroid.childFile('gradlew').readAsStringSync(),
          equals('existing gradlew'));

      expect(sampleAppAndroid
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.jar')
        .existsSync(), isTrue);

      expect(sampleAppAndroid
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.properties')
        .existsSync(), isTrue);

      expect(sampleAppAndroid
        .childDirectory('gradle')
        .childDirectory('wrapper')
        .childFile('gradle-wrapper.properties')
        .readAsStringSync(),
          'distributionBase=GRADLE_USER_HOME\n'
          'distributionPath=wrapper/dists\n'
          'zipStoreBase=GRADLE_USER_HOME\n'
          'zipStorePath=wrapper/dists\n'
          'distributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.2-all.zip\n');
    }, overrides: <Type, Generator>{
      Cache: () => Cache.test(rootOverride: tempDir, fileSystem: memoryFileSystem),
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
    });
  });


  group('migrateToR8', () {
    MemoryFileSystem memoryFileSystem;

    setUp(() {
      memoryFileSystem = MemoryFileSystem.test();
    });

    testUsingContext("throws ToolExit if gradle.properties doesn't exist", () {
      final Directory sampleAppAndroid = globals.fs.directory('/sample-app/android');
      sampleAppAndroid.createSync(recursive: true);

      expect(() {
        gradleUtils.migrateToR8(sampleAppAndroid);
      }, throwsToolExit(message: 'Expected file ${sampleAppAndroid.path}'));

    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingContext('throws ToolExit if it cannot write gradle.properties', () {
      final MockDirectory sampleAppAndroid = MockDirectory();
      final MockFile gradleProperties = MockFile();

      when(gradleProperties.path).thenReturn('foo/gradle.properties');
      when(gradleProperties.existsSync()).thenReturn(true);
      when(gradleProperties.readAsStringSync()).thenReturn('');
      when(gradleProperties.writeAsStringSync('android.enableR8=true\n', mode: FileMode.append))
        .thenThrow(const FileSystemException());

      when(sampleAppAndroid.childFile('gradle.properties'))
        .thenReturn(gradleProperties);

      expect(() {
        gradleUtils.migrateToR8(sampleAppAndroid);
      },
      throwsToolExit(message:
        'The tool failed to add `android.enableR8=true` to foo/gradle.properties. '
        'Please update the file manually and try this command again.'));
    });

    testUsingContext('does not update gradle.properties if it already uses R8', () {
      final Directory sampleAppAndroid = globals.fs.directory('/sample-app/android');
      sampleAppAndroid.createSync(recursive: true);
      sampleAppAndroid.childFile('gradle.properties')
        .writeAsStringSync('android.enableR8=true');

      gradleUtils.migrateToR8(sampleAppAndroid);

      expect(testLogger.traceText,
        contains('gradle.properties already sets `android.enableR8`'));
      expect(sampleAppAndroid.childFile('gradle.properties').readAsStringSync(),
        equals('android.enableR8=true'));
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingContext('sets android.enableR8=true', () {
      final Directory sampleAppAndroid = globals.fs.directory('/sample-app/android');
      sampleAppAndroid.createSync(recursive: true);
      sampleAppAndroid.childFile('gradle.properties')
        .writeAsStringSync('org.gradle.jvmargs=-Xmx1536M\n');

      gradleUtils.migrateToR8(sampleAppAndroid);

      expect(testLogger.traceText, contains('set `android.enableR8=true` in gradle.properties'));
      expect(
        sampleAppAndroid.childFile('gradle.properties').readAsStringSync(),
        equals(
          'org.gradle.jvmargs=-Xmx1536M\n'
          'android.enableR8=true\n'
        ),
      );
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingContext('appends android.enableR8=true to the new line', () {
      final Directory sampleAppAndroid = globals.fs.directory('/sample-app/android');
      sampleAppAndroid.createSync(recursive: true);
      sampleAppAndroid.childFile('gradle.properties')
        .writeAsStringSync('org.gradle.jvmargs=-Xmx1536M');

      gradleUtils.migrateToR8(sampleAppAndroid);

      expect(testLogger.traceText, contains('set `android.enableR8=true` in gradle.properties'));
      expect(
        sampleAppAndroid.childFile('gradle.properties').readAsStringSync(),
        equals(
          'org.gradle.jvmargs=-Xmx1536M\n'
          'android.enableR8=true\n'
        ),
      );
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any()
    });
  });

  group('GradleUtils.getExecutable', () {
    final String gradlewFilename = globals.platform.isWindows ? 'gradlew.bat' : 'gradlew';

    MemoryFileSystem memoryFileSystem;
    OperatingSystemUtils operatingSystemUtils;
    MockGradleUtils gradleUtils;

    setUp(() {
      memoryFileSystem = MemoryFileSystem.test();
      operatingSystemUtils = MockOperatingSystemUtils();
      gradleUtils = MockGradleUtils();
    });

    testUsingContext('returns the gradlew path', () {
      final Directory androidDirectory = globals.fs.directory('/android')..createSync();
      androidDirectory.childFile('gradlew').createSync();
      androidDirectory.childFile('gradlew.bat').createSync();
      androidDirectory.childFile('gradle.properties').createSync();

      when(gradleUtils.injectGradleWrapperIfNeeded(any)).thenReturn(null);
      when(gradleUtils.migrateToR8(any)).thenReturn(null);

      expect(
        GradleUtils().getExecutable(FlutterProject.current()),
        androidDirectory.childFile(gradlewFilename).path,
      );
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      OperatingSystemUtils: () => operatingSystemUtils,
      GradleUtils: () => gradleUtils,
    });

    testUsingContext('gives execute permission to gradle', () {
      final FlutterProject flutterProject = MockFlutterProject();
      final AndroidProject androidProject = MockAndroidProject();
      when(flutterProject.android).thenReturn(androidProject);

      final FileStat gradleStat = MockFileStat();
      when(gradleStat.mode).thenReturn(444);

      final File gradlew = MockFile();
      when(gradlew.path).thenReturn('gradlew');
      when(gradlew.absolute).thenReturn(gradlew);
      when(gradlew.statSync()).thenReturn(gradleStat);
      when(gradlew.existsSync()).thenReturn(true);

      final Directory androidDirectory = MockDirectory();
      when(androidDirectory.childFile(gradlewFilename)).thenReturn(gradlew);
      when(androidProject.hostAppGradleRoot).thenReturn(androidDirectory);

      when(gradleUtils.injectGradleWrapperIfNeeded(any)).thenReturn(null);
      when(gradleUtils.migrateToR8(any)).thenReturn(null);

      GradleUtils().getExecutable(flutterProject);

      verify(operatingSystemUtils.makeExecutable(gradlew)).called(1);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      OperatingSystemUtils: () => operatingSystemUtils,
      GradleUtils: () => gradleUtils,
    });

    testUsingContext('gives execute permission to gradle even when not all permission flags are set', () {
      final FlutterProject flutterProject = MockFlutterProject();
      final AndroidProject androidProject = MockAndroidProject();
      when(flutterProject.android).thenReturn(androidProject);

      final FileStat gradleStat = MockFileStat();
      when(gradleStat.mode).thenReturn(400);

      final File gradlew = MockFile();
      when(gradlew.path).thenReturn('gradlew');
      when(gradlew.absolute).thenReturn(gradlew);
      when(gradlew.statSync()).thenReturn(gradleStat);
      when(gradlew.existsSync()).thenReturn(true);

      final Directory androidDirectory = MockDirectory();
      when(androidDirectory.childFile(gradlewFilename)).thenReturn(gradlew);
      when(androidProject.hostAppGradleRoot).thenReturn(androidDirectory);

      when(gradleUtils.injectGradleWrapperIfNeeded(any)).thenReturn(null);
      when(gradleUtils.migrateToR8(any)).thenReturn(null);

      GradleUtils().getExecutable(flutterProject);

      verify(operatingSystemUtils.makeExecutable(gradlew)).called(1);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      OperatingSystemUtils: () => operatingSystemUtils,
      GradleUtils: () => gradleUtils,
    });

    testUsingContext("doesn't give execute permission to gradle if not needed", () {
      final FlutterProject flutterProject = MockFlutterProject();
      final AndroidProject androidProject = MockAndroidProject();
      when(flutterProject.android).thenReturn(androidProject);

      final FileStat gradleStat = MockFileStat();
      when(gradleStat.mode).thenReturn(0x49 /* a+x */);

      final File gradlew = MockFile();
      when(gradlew.path).thenReturn('gradlew');
      when(gradlew.absolute).thenReturn(gradlew);
      when(gradlew.statSync()).thenReturn(gradleStat);
      when(gradlew.existsSync()).thenReturn(true);

      final Directory androidDirectory = MockDirectory();
      when(androidDirectory.childFile(gradlewFilename)).thenReturn(gradlew);
      when(androidProject.hostAppGradleRoot).thenReturn(androidDirectory);

      when(gradleUtils.injectGradleWrapperIfNeeded(any)).thenReturn(null);
      when(gradleUtils.migrateToR8(any)).thenReturn(null);

      GradleUtils().getExecutable(flutterProject);

      verifyNever(operatingSystemUtils.makeExecutable(gradlew));
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      OperatingSystemUtils: () => operatingSystemUtils,
      GradleUtils: () => gradleUtils,
    });
  });
}

class MockAndroidProject extends Mock implements AndroidProject {}
class MockDirectory extends Mock implements Directory {}
class MockFile extends Mock implements File {}
class MockFileStat extends Mock implements FileStat {}
class MockFlutterProject extends Mock implements FlutterProject {}
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
class MockGradleUtils extends Mock implements GradleUtils {}
