// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. 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:async';
import 'dart:convert';
import 'dart:io';

import 'package:dartdev/src/commands/create.dart';
import 'package:dartdev/src/templates.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import '../utils.dart';

void main() {
  ensureRunFromSdkBinDart();

  group('create integration', defineCreateTests, timeout: longTimeout);
}

void defineCreateTests() {
  // Create tests for each template.
  for (String templateId
      in CreateCommand.legalTemplateIds(includeDeprecated: true)) {
    test(templateId, () async {
      const projectName = 'template_project';
      final p = project();
      final templateGenerator = getGenerator(templateId)!;

      print('$templateId: creating template');
      ProcessResult createResult = await p.run([
        'create',
        '--force',
        '--template',
        templateId,
        projectName,
      ]);
      printOnFailure(createResult.stdout);
      printOnFailure(createResult.stderr);
      expect(createResult.exitCode, 0, reason: createResult.stderr);

      // Validate that the project analyzes cleanly.
      print('$templateId: analyzing generated project');
      ProcessResult analyzeResult = await p.runAnalyze(
        ['--fatal-infos', projectName],
        workingDir: p.dir.path,
      );
      expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout);

      // Validate that the code is well formatted.
      print('$templateId: checking formatting');
      ProcessResult formatResult = await p.run([
        'format',
        '--output',
        'none',
        '--set-exit-if-changed',
        projectName,
      ]);
      expect(formatResult.exitCode, 0, reason: formatResult.stdout);

      // Process the execution instructions provided by the template.
      final runCommands = templateGenerator
          .getInstallInstructions(
            projectName,
            scriptPath: projectName,
          )
          .split('\n')
          // Remove directory change instructions.
          .sublist(1)
          .map((command) => command.trim())
          .map((command) {
        final commandParts = command.split(' ');
        if (command.startsWith('dart ')) {
          return commandParts.sublist(1);
        }
        return commandParts;
      }).toList();

      print('$templateId: running the following commands:');
      for (final command in runCommands) {
        print('  $command');
      }

      final isServerTemplate = templateGenerator.categories.contains('server');
      final isWebTemplate = templateGenerator.categories.contains('web');
      final workingDir = path.join(p.dirPath, projectName);

      // Execute the templates run instructions.
      for (int i = 0; i < runCommands.length; ++i) {
        // The last command is always the command to execute the code generated
        // by the template.
        final isLastCommand = i == runCommands.length - 1;
        final command = runCommands[i];
        Process process;
        print('[${i + 1} / ${runCommands.length}] Running "$command"...');
        if (isLastCommand && isWebTemplate) {
          // The web template uses `webdev` to execute, not `dart`, so don't
          // run the test through the project utility method.
          process = await Process.start(
              path.join(
                p.pubCacheBinPath,
                Platform.isWindows ? '${command.first}.bat' : command.first,
              ),
              [
                ...command.sublist(1),
                'web:0', // Allow for binding to a random available port.
              ],
              workingDirectory: workingDir,
              environment: {
                'PUB_CACHE': p.pubCachePath,
                'PATH': path.dirname(Platform.resolvedExecutable) +
                    (Platform.isWindows ? ';' : ':') +
                    Platform.environment['PATH']!,
              });
        } else {
          process = await p.start(
            command,
            workingDir: workingDir,
          );
        }

        if (isLastCommand && (isServerTemplate || isWebTemplate)) {
          final completer = Completer<void>();
          late StreamSubscription stdoutSub;
          late StreamSubscription stderrSub;
          // Listen for well-known output from specific templates to determine
          // if they've executed correctly. These templates won't exit on their
          // own, so we'll need to terminate the process once we've verified it
          // runs correctly.
          var hasError = false;
          stdoutSub = process.stdout.transform(utf8.decoder).listen((e) {
            print('stdout: $e');
            if (e.contains('[SEVERE]') ||
                (isServerTemplate && e.contains('Server listening on port')) ||
                (isWebTemplate && e.contains('Succeeded after'))) {
              if (e.contains('[SEVERE]')) {
                hasError = true;
              }
              stderrSub.cancel();
              stdoutSub.cancel();
              process.kill();
              completer.complete();
            }
          });
          stderrSub = process.stderr.transform(utf8.decoder).listen((e) {
            print('stderr: $e');
            hasError = true;
            stderrSub.cancel();
            stdoutSub.cancel();
            process.kill();
            completer.complete();
          });
          await completer.future;
          expect(hasError, isFalse, reason: 'Command $command failed.');

          // Since we had to terminate the process manually, we aren't certain
          // as to what the exit code will be on all platforms (should be -15
          // for POSIX systems), so we'll just wait for the process to exit
          // here.
          await process.exitCode;
        } else {
          final output = <String>[];
          final errors = <String>[];
          process.stdout.transform(utf8.decoder).listen(output.add);
          process.stderr.transform(utf8.decoder).listen(errors.add);

          // If the sample should exit on its own, it should always result in
          // an exit code of 0.
          final duration = const Duration(seconds: 60);
          final exitCode =
              await process.exitCode.timeout(duration, onTimeout: () {
            print('Command $command timed out');
            return -1;
          });
          if (exitCode != 0) {
            print('Command $command exited with code $exitCode');
            print('Output: \n${output.join('\n')}');
            print('Errors: \n${errors.join('\n')}');
          }
          expect(exitCode, 0);
        }
        print('[${i + 1} / ${runCommands.length}] Done "$command".');
      }
    });
  }
}
