// 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:convert';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:process_runner/process_runner.dart';

// This program enables testing of private interfaces in the flutter package.
//
// See README.md for more information.

final Directory flutterRoot =
  Directory(path.fromUri(Platform.script)).absolute.parent.parent.parent.parent.parent;
final Directory flutterPackageDir = Directory(path.join(flutterRoot.path, 'packages', 'flutter'));
final Directory testPrivateDir = Directory(path.join(flutterPackageDir.path, 'test_private'));
final Directory privateTestsDir = Directory(path.join(testPrivateDir.path, 'test'));

void _usage() {
  print('Usage: test_private.dart [--help] [--temp-dir=<temp_dir>]');
  print('''
    --help      Print a usage message.
    --temp-dir  A location where temporary files may be written. Defaults to a
                directory in the system temp folder. If a temp_dir is not
                specified, then the default temp_dir will be created, used, and
                removed automatically.
    ''');
}

Future<void> main(List<String> args) async {
  // TODO(gspencergoog): Convert to using the args package once it has been
  // converted to be non-nullable by default.
  if (args.isNotEmpty && args[0] == '--help') {
    _usage();
    exit(0);
  }

  void errorExit(String message, {int exitCode = -1}) {
    stderr.write('Error: $message\n\n');
    _usage();
    exit(exitCode);
  }

  if (args.length > 2) {
    errorExit('Too many arguments.');
  }

  String? tempDirArg;
  if (args.isNotEmpty) {
    if (args[0].startsWith('--temp-dir')) {
      if (args[0].startsWith('--temp-dir=')) {
        tempDirArg = args[0].replaceFirst('--temp-dir=', '');
      } else {
        if (args.length < 2) {
          errorExit('Not enough arguments to --temp-dir');
        }
        tempDirArg = args[1];
      }
    } else {
      errorExit('Invalid arguments ${args.join(' ')}.');
    }
  }

  Directory tempDir;
  bool removeTempDir = false;
  if (tempDirArg == null || tempDirArg.isEmpty) {
    tempDir = Directory.systemTemp.createTempSync('flutter_package.');
    removeTempDir = true;
  } else {
    tempDir = Directory(tempDirArg);
    if (!tempDir.existsSync()) {
      errorExit("Temporary directory $tempDirArg doesn't exist.");
    }
  }

  bool success = true;
  try {
    await for (final TestCase testCase in getTestCases(tempDir)) {
      stderr.writeln('Analyzing test case $testCase');
      if (!testCase.setUp()) {
        stderr.writeln('Unable to set up $testCase');
        success = false;
        break;
      }
      if (!await testCase.runAnalyzer()) {
        stderr.writeln('Test case $testCase failed analysis.');
        success = false;
        break;
      } else {
        stderr.writeln('Test case $testCase passed analysis.');
      }
      stderr.writeln('Running test case $testCase');
      if (!await testCase.runTests()) {
        stderr.writeln('Test case $testCase failed.');
        success = false;
        break;
      } else {
        stderr.writeln('Test case $testCase succeeded.');
      }
    }
  } finally {
    if (removeTempDir) {
      tempDir.deleteSync(recursive: true);
    }
  }
  exit(success ? 0 : 1);
}

File makeAbsolute(File file, {Directory? workingDirectory}) {
  workingDirectory ??= Directory.current;
  return File(path.join(workingDirectory.absolute.path, file.path));
}

/// A test case representing a private test file that should be run.
///
/// It is loaded from a JSON manifest file that contains a list of dependencies
/// to copy, a list of test files themselves, and a pubspec file.
///
/// The dependencies are copied into the test area with the same relative path.
///
/// The test files are copied to the root of the test area.
///
/// The pubspec file is copied to the root of the test area too, but renamed to
/// "pubspec.yaml".
class TestCase {
  TestCase.fromManifest(this.manifest, this.tmpdir) {
    _json = jsonDecode(manifest.readAsStringSync()) as Map<String, dynamic>;
    tmpdir.createSync(recursive: true);
    assert(tmpdir.existsSync());
  }

  final File manifest;
  final Directory tmpdir;

  Map<String, dynamic> _json = <String, dynamic>{};

  Iterable<File> _getList(String name) sync* {
    for (final dynamic entry in _json[name] as List<dynamic>) {
      final String name = entry as String;
      yield File(path.joinAll(name.split('/')));
    }
  }

  Iterable<File> get dependencies => _getList('deps');
  Iterable<File> get testDependencies => _getList('test_deps');
  Iterable<File> get tests => _getList('tests');
  File get pubspec => File(_json['pubspec'] as String);

  bool setUp() {
    // Copy the manifest tests and deps to the same relative path under the
    // tmpdir.
    for (final File file in dependencies) {
      try {
        final Directory destDir = Directory(path.join(tmpdir.absolute.path, file.parent.path));
        destDir.createSync(recursive: true);
        final File absFile = makeAbsolute(file, workingDirectory: flutterPackageDir);
        final String destination = path.join(tmpdir.absolute.path, file.path);
        absFile.copySync(destination);
      } on FileSystemException catch (e) {
        stderr.writeln('Problem copying manifest dep file ${file.path} to ${tmpdir.path}: $e');
        return false;
      }
    }
    for (final File file in testDependencies) {
      try {
        final Directory destDir = Directory(path.join(tmpdir.absolute.path, 'lib', file.parent.path));
        destDir.createSync(recursive: true);
        final File absFile = makeAbsolute(file, workingDirectory: flutterPackageDir);
        final String destination = path.join(tmpdir.absolute.path, 'lib', file.path);
        absFile.copySync(destination);
      } on FileSystemException catch (e) {
        stderr.writeln('Problem copying manifest test_dep file ${file.path} to ${tmpdir.path}: $e');
        return false;
      }
    }
    // Copy the test files into the tmpdir's lib directory.
    for (final File file in tests) {
      String destination = tmpdir.path;
      try {
        final File absFile = makeAbsolute(file, workingDirectory: privateTestsDir);
        // Copy the file, but without the ".tmpl" extension.
        destination = path.join(tmpdir.absolute.path, 'lib', path.basenameWithoutExtension(file.path));
        absFile.copySync(destination);
      } on FileSystemException catch (e) {
        stderr.writeln('Problem copying test ${file.path} to $destination: $e');
        return false;
      }
    }

    // Copy the pubspec to the right place.
    makeAbsolute(pubspec, workingDirectory: privateTestsDir)
        .copySync(path.join(tmpdir.absolute.path, 'pubspec.yaml'));

    // Use Flutter's analysis_options.yaml file from packages/flutter.
    File(path.join(tmpdir.absolute.path, 'analysis_options.yaml'))
        .writeAsStringSync('include: ${path.toUri(path.join(flutterRoot.path, 'packages', 'flutter', 'analysis_options.yaml'))}');

    return true;
  }

  Future<bool> runAnalyzer() async {
    final String flutter = path.join(flutterRoot.path, 'bin', 'flutter');
    final ProcessRunner runner = ProcessRunner(
      defaultWorkingDirectory: tmpdir.absolute,
      printOutputDefault: true,
    );
    final ProcessRunnerResult result = await runner.runProcess(
      <String>[flutter, 'analyze', '--current-package', '--pub', '--congratulate', '.'],
      failOk: true,
    );
    if (result.exitCode != 0) {
      return false;
    }
    return true;
  }

  Future<bool> runTests() async {
    final ProcessRunner runner = ProcessRunner(
      defaultWorkingDirectory: tmpdir.absolute,
      printOutputDefault: true,
    );
    final String flutter = path.join(flutterRoot.path, 'bin', 'flutter');
    for (final File test in tests) {
      final String testPath = path.join(path.dirname(test.path), 'lib', path.basenameWithoutExtension(test.path));
      final ProcessRunnerResult result = await runner.runProcess(
        <String>[flutter, 'test', '--enable-experiment=non-nullable', '--no-sound-null-safety', '--null-assertions', testPath],
        failOk: true,
      );
      if (result.exitCode != 0) {
        return false;
      }
    }
    return true;
  }

  @override
  String toString() {
    return path.basenameWithoutExtension(manifest.path);
  }
}

Stream<TestCase> getTestCases(Directory tmpdir) async* {
  final Directory testDir = Directory(path.join(testPrivateDir.path, 'test'));
  await for (final FileSystemEntity entity in testDir.list(recursive: true)) {
    if (path.split(entity.path).where((String element) => element.startsWith('.')).isNotEmpty) {
      // Skip hidden files, directories, and the files inside them, like
      // .dart_tool, which contains a (non-hidden) .json file.
      continue;
    }
    if (entity is File && path.basename(entity.path).endsWith('_test.json')) {
      print('Found manifest ${entity.path}');
      final Directory testTmpDir =
          Directory(path.join(tmpdir.absolute.path, path.basenameWithoutExtension(entity.path)));
      yield TestCase.fromManifest(entity, testTmpDir);
    }
  }
}
