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

// @dart = 2.8

import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';

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

void main() {
  /// Verifies that `dart migrate` will run successfully on the default `flutter create`
  /// template.
  group('dart migrate', () {
    testWithoutContext('dart migrate succeeds on flutter create template', () async {
      Directory tempDir;
      try {
        tempDir = await _createProject(tempDir);
        await _migrate(tempDir);
        await _analyze(tempDir);
      } finally {
        tempDir?.deleteSync(recursive: true);
      }
    });

    /// Verifies that `dart migrate` will run successfully on the module template
    /// used by `flutter create --template=module`.
    testWithoutContext('dart migrate succeeds on module template', () async {
      Directory tempDir;
      try {
        tempDir = await _createProject(tempDir, <String>['--template=module']);
        await _migrate(tempDir);
        await _analyze(tempDir);
      } finally {
        tempDir?.deleteSync(recursive: true);
      }
    });

    /// Verifies that `dart migrate` will run successfully on the module template
    /// used by `flutter create --template=plugin`.
    testWithoutContext('dart migrate succeeds on plugin template', () async {
      Directory tempDir;
      try {
        tempDir = await _createProject(tempDir, <String>['--template=plugin']);
        await _migrate(tempDir);
        await _analyze(tempDir);
      } finally {
        tempDir?.deleteSync(recursive: true);
      }
    });

    /// Verifies that `dart migrate` will run successfully on the module template
    /// used by `flutter create --template=package`.
    testWithoutContext('dart migrate succeeds on package template', () async {
      Directory tempDir;
      try {
        tempDir = await _createProject(tempDir, <String>['--template=package']);
        await _migrate(tempDir);
        await _analyze(tempDir);
      } finally {
        tempDir?.deleteSync(recursive: true);
      }
    });
  }, timeout: const Timeout(Duration(seconds: 90)));
}

Future<Directory> _createProject(Directory tempDir, [List<String> extraAgs]) async {
  tempDir = createResolvedTempDirectorySync('dart_migrate_test.');
  final ProcessResult createResult = await processManager.run(<String>[
    _flutterBin,
    'create',
    if (extraAgs != null)
      ...extraAgs,
    'foo',
  ], workingDirectory: tempDir.path);
  if (createResult.exitCode != 0) {
    fail('flutter create did not work: ${createResult.stdout}${createResult.stderr}');
  }
  return tempDir;
}

Future<void> _migrate(Directory tempDir) async {
  final ProcessResult migrateResult = await processManager.run(<String>[
    _dartBin,
    'migrate',
    '--apply-changes',
  ], workingDirectory: fileSystem.path.join(tempDir.path, 'foo'));
  if (migrateResult.exitCode != 0) {
    fail('dart migrate did not work: ${migrateResult.stdout}${migrateResult.stderr}');
  }
}

Future<void> _analyze(Directory tempDir) async {
  final ProcessResult analyzeResult = await processManager.run(<String>[
    _flutterBin,
    'analyze',
  ], workingDirectory: fileSystem.path.join(tempDir.path, 'foo'));
  if (analyzeResult.exitCode != 0) {
    fail('flutter analyze had errors: ${analyzeResult.stdout}${analyzeResult.stderr}');
  }
}

String get _flutterBin => fileSystem.path.join(getFlutterRoot(), 'bin', platform.isWindows ? 'flutter.bat' : 'flutter');
String get _dartBin => fileSystem.path.join(getFlutterRoot(), 'bin', platform.isWindows ? 'dart.bat' : 'dart');
