// 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.

// This script generates `android/build.gradle` for each directory specify in the stdin.
// Then it generate the lockfiles for each Gradle project.
// To regenerate these files, run `find . -type d -name 'android' | dart dev/tools/bin/generate_gradle_lockfiles.dart`

import 'dart:io';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:path/path.dart' as path;

void main(List<String> arguments) {
  print(
    "Usage: find . -type d -name 'android' | dart dev/tools/bin/generate_gradle_lockfiles.dart\n"
    'If you would rather enter the files manually, just run `dart dev/tools/bin/generate_gradle_lockfiles.dart`,\n'
    "enter the absolute paths to the app's android directory, then press CTRL-D.\n"
  );

  const FileSystem fileSystem = LocalFileSystem();
  final List<String> androidDirectories = getFilesFromStdin();

  for (final String androidDirectoryPath in androidDirectories) {
    final Directory androidDirectory = fileSystem.directory(path.normalize(androidDirectoryPath));

    if (!androidDirectory.existsSync()) {
      throw '$androidDirectory does not exist';
    }

    final File rootBuildGradle = androidDirectory.childFile('build.gradle');
    if (!rootBuildGradle.existsSync()) {
      print('${rootBuildGradle.path} does not exist - skipping');
      continue;
    }

    final File settingsGradle = androidDirectory.childFile('settings.gradle');
    if (!settingsGradle.existsSync()) {
      print('${settingsGradle.path} does not exist - skipping');
      continue;
    }

    if (settingsGradle.readAsStringSync().contains('include_flutter.groovy')) {
      print('${settingsGradle.path} add to app - skipping');
      continue;
    }

    if (!androidDirectory.childDirectory('app').existsSync()) {
      print('${rootBuildGradle.path} is not an app - skipping');
      continue;
    }

    if (!androidDirectory.parent.childFile('pubspec.yaml').existsSync()) {
      print('${rootBuildGradle.path} no pubspec.yaml in parent directory - skipping');
      continue;
    }

    if (androidDirectory.parent.childFile('pubspec.yaml').readAsStringSync().contains('deferred-components')) {
      print('${rootBuildGradle.path} uses deferred components - skipping');
      continue;
    }

    if (!androidDirectory.parent
        .childDirectory('lib')
        .childFile('main.dart')
        .existsSync()) {
      print('${rootBuildGradle.path} no main.dart under lib - skipping');
      continue;
    }

    print('Processing ${androidDirectory.path}');

    try {
      androidDirectory.childFile('buildscript-gradle.lockfile').deleteSync();
    } on FileSystemException {
      // noop
    }

    rootBuildGradle.writeAsStringSync(rootGradleFileContent);
    settingsGradle.writeAsStringSync(settingGradleFile);

    final String appDirectory = androidDirectory.parent.absolute.path;

    // Fetch pub dependencies.
    exec('flutter', <String>['pub', 'get'], workingDirectory: appDirectory);

    // Verify that the Gradlew wrapper exists.
    final File gradleWrapper = androidDirectory.childFile('gradlew');
    // Generate Gradle wrapper if it doesn't exists.
    // This logic is embedded within the Flutter tool.
    // To generate the wrapper, build a flavor that doesn't exist.
    if (!gradleWrapper.existsSync()) {
      Process.runSync(
        'flutter',
        <String>['build', 'apk', '--debug', '--flavor=does-not-exist'],
        workingDirectory: appDirectory,
      );
    }

    // Generate lock files.
    exec(
      gradleWrapper.absolute.path,
      <String>[':generateLockfiles'],
      workingDirectory: androidDirectory.absolute.path,
    );

    print('Processed');
  }
}

List<String> getFilesFromStdin() {
  final List<String> files = <String>[];
  while (true) {
    final String? file = stdin.readLineSync();
    if (file == null) {
      break;
    }
    files.add(file);
  }
  return files;
}

void exec(
  String cmd,
  List<String> args, {
  String? workingDirectory,
}) {
  final ProcessResult result = Process.runSync(cmd, args, workingDirectory: workingDirectory);
  if (result.exitCode != 0) {
    throw ProcessException(
        cmd, args, '${result.stdout}${result.stderr}', result.exitCode);
  }
}

const String rootGradleFileContent = r'''
// 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.

// This file is auto generated.
// To update all the build.gradle files in the Flutter repo,
// See dev/tools/bin/generate_gradle_lockfiles.dart.

buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }

    configurations.classpath {
        resolutionStrategy.activateDependencyLocking()
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'

subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
    dependencyLocking {
        ignoredDependencies.add('io.flutter:*')
        lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile")
        if (!project.hasProperty('local-engine-repo')) {
          lockAllConfigurations()
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
''';

const String settingGradleFile = r'''
// 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.

// This file is auto generated.
// To update all the settings.gradle files in the Flutter repo,
// See dev/tools/bin/generate_gradle_lockfiles.dart.

include ':app'

enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')

def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()

assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }

def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
''';
