// Copyright 2013 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:args/args.dart';
import 'package:path/path.dart' as path;
import 'package:process/process.dart';

const LocalProcessManager processManager = LocalProcessManager();

/// Runs the Android SDK Lint tool on flutter/shell/platform/android.
///
/// This script scans the flutter/shell/platform/android directory for Java
/// files to build a `project.xml` file.  This file is then passed to the lint
/// tool. If an `--html` flag is also passed in, HTML output is reqeusted in the
/// directory for the optional `--out` parameter, which defaults to
/// `lint_report`. Otherwise the output is printed to STDOUT.
///
/// The `--in` parameter may be specified to force this script to scan a
/// specific location for the engine repository, and expects to be given the
/// `src` directory that contains both `third_party` and `flutter`.
///
/// At the time of this writing, the Android Lint tool doesn't work well with
/// Java > 1.8.  This script will print a warning if you are not running
/// Java 1.8.
Future<void> main(List<String> args) async {
  final ArgParser argParser = setupOptions();
  final int exitCode = await runLint(argParser, argParser.parse(args));
  exit(exitCode);
}

Future<int> runLint(ArgParser argParser, ArgResults argResults) async {
  final String inArgument = argResults['in'] as String;
  final Directory androidDir = Directory(path.join(
    inArgument,
    'flutter',
    'shell',
    'platform',
    'android',
  ));
  if (!androidDir.existsSync()) {
    print('This command must be run from the engine/src directory, '
        'or be passed that directory as the --in parameter.\n');
    print(argParser.usage);
    return -1;
  }

  final Directory androidSdkDir = Directory(
    path.join(inArgument, 'third_party', 'android_tools', 'sdk'),
  );

  if (!androidSdkDir.existsSync()) {
    print('The Android SDK for this engine is missing from the '
        'third_party/android_tools directory. Have you run gclient sync?\n');
    print(argParser.usage);
    return -1;
  }

  final bool rebaseline = argResults['rebaseline'] as bool;
  if (rebaseline) {
    print('Removing previous baseline.xml...');
    final File baselineXml = File(baselineXmlPath);
    if (baselineXml.existsSync()) {
      await baselineXml.delete();
    }
  }
  print('Preparing project.xml...');
  final IOSink projectXml = File(projectXmlPath).openWrite();
  projectXml.write('''
<!-- THIS FILE IS GENERATED. PLEASE USE THE INCLUDED DART PROGRAM  WHICH -->
<!-- WILL AUTOMATICALLY FIND ALL .java FILES AND INCLUDE THEM HERE       -->
<project>
  <sdk dir="${androidSdkDir.path}" />
  <module name="FlutterEngine" android="true" library="true" compile-sdk-version="android-S">
  <manifest file="${path.join(androidDir.path, 'AndroidManifest.xml')}" />
''');
  for (final FileSystemEntity entity in androidDir.listSync(recursive: true)) {
    if (!entity.path.endsWith('.java')) {
      continue;
    }
    projectXml.writeln('    <src file="${entity.path}" />');
  }

  projectXml.write('''
  </module>
</project>
''');
  await projectXml.close();
  print('Wrote project.xml, starting lint...');
  final List<String> lintArgs = <String>[
    path.join(androidSdkDir.path, 'cmdline-tools', 'latest', 'bin', 'lint'),
    '--project', projectXmlPath,
    '--compile-sdk-version', '31',
    '--showall',
    '--exitcode', // Set non-zero exit code on errors
    '-Wall',
    '-Werror',
    '--baseline',
    baselineXmlPath,
  ];
  final bool html = argResults['html'] as bool;
  if (html) {
    lintArgs.addAll(<String>['--html', argResults['out'] as String]);
  }
  final String javahome = getJavaHome(inArgument);
  print('Using JAVA_HOME=$javahome');
  final Process lintProcess = await processManager.start(
    lintArgs,
    environment: <String, String>{
      'JAVA_HOME': javahome,
    },
  );
  lintProcess.stdout.pipe(stdout);
  lintProcess.stderr.pipe(stderr);
  return lintProcess.exitCode;
}

/// Prepares an [ArgParser] for this script.
ArgParser setupOptions() {
  final ArgParser argParser = ArgParser();
  argParser
    ..addOption(
      'in',
      help: 'The path to `engine/src`.',
      defaultsTo: path.relative(
        path.join(
          projectDir,
          '..',
          '..',
          '..',
        ),
      ),
    )
    ..addFlag(
      'help',
      help: 'Print usage of the command.',
      negatable: false,
      defaultsTo: false,
    )
    ..addFlag(
      'rebaseline',
      help: 'Recalculates the baseline for errors and warnings '
          'in this project.',
      negatable: false,
      defaultsTo: false,
    )
    ..addFlag(
      'html',
      help: 'Creates an HTML output for this report instead of printing '
          'command line output.',
      negatable: false,
      defaultsTo: false,
    )
    ..addOption(
      'out',
      help: 'The path to write the generated HTML report. Ignored if '
          '--html is not also true.',
      defaultsTo: path.join(projectDir, 'lint_report'),
    );

  return argParser;
}

String getJavaHome(String src) {
  if (Platform.isMacOS) {
    return path.normalize('$src/third_party/java/openjdk/Contents/Home/');
  }
  return path.normalize('$src/third_party/java/openjdk/');
}

/// The root directory of this project.
String get projectDir => path.dirname(
      path.dirname(
        path.fromUri(Platform.script),
      ),
    );

/// The path to use for project.xml, which tells the linter where to find source
/// files.
String get projectXmlPath => path.join(projectDir, 'project.xml');

/// The path to use for baseline.xml, which tells the linter what errors or
/// warnings to ignore.
String get baselineXmlPath => path.join(projectDir, 'baseline.xml');
