// Copyright (c) 2015, 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.

library test_utils;

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:dartdoc/dartdoc.dart';
import 'package:dartdoc/src/html/html_generator.dart';
import 'package:dartdoc/src/model.dart';
import 'package:dartdoc/src/package_meta.dart';
import 'package:path/path.dart' as path;

final RegExp quotables = RegExp(r'[ "\r\n\$]');
final RegExp observatoryPortRegexp =
    RegExp(r'^Observatory listening on http://.*:(\d+)');

Directory sdkDir;
PackageMeta sdkPackageMeta;
PackageGraph testPackageGraph;
PackageGraph testPackageGraphExperiments;
PackageGraph testPackageGraphGinormous;
PackageGraph testPackageGraphSmall;
PackageGraph testPackageGraphErrors;
PackageGraph testPackageGraphSdk;

final Directory testPackageBadDir = Directory('testing/test_package_bad');
final Directory testPackageDir = Directory('testing/test_package');
final Directory testPackageExperimentsDir =
    Directory('testing/test_package_experiments');
final Directory testPackageMinimumDir =
    Directory('testing/test_package_minimum');
final Directory testPackageWithEmbedderYaml =
    Directory('testing/test_package_embedder_yaml');
final Directory testPackageWithNoReadme =
    Directory('testing/test_package_small');
final Directory testPackageIncludeExclude =
    Directory('testing/test_package_include_exclude');
final Directory testPackageImportExportError =
    Directory('testing/test_package_import_export_error');
final Directory testPackageOptions = Directory('testing/test_package_options');
final Directory testPackageOptionsImporter =
    Directory('testing/test_package_options_importer');
final Directory testPackageToolError =
    Directory('testing/test_package_tool_error');

/// Convenience factory to build a [DartdocGeneratorOptionContext] and associate
/// it with a [DartdocOptionSet] based on the current working directory and/or
/// the '--input' flag.
Future<DartdocGeneratorOptionContext> generatorContextFromArgv(
    List<String> argv) async {
  DartdocOptionSet optionSet = await DartdocOptionSet.fromOptionGenerators(
      'dartdoc', [createDartdocOptions, createGeneratorOptions]);
  optionSet.parseArguments(argv);
  return DartdocGeneratorOptionContext(optionSet, null);
}

/// Convenience factory to build a [DartdocOptionContext] and associate it with a
/// [DartdocOptionSet] based on the current working directory.
Future<DartdocOptionContext> contextFromArgv(List<String> argv) async {
  DartdocOptionSet optionSet = await DartdocOptionSet.fromOptionGenerators(
      'dartdoc', [createDartdocOptions]);
  optionSet.parseArguments(argv);
  return DartdocOptionContext(optionSet, Directory.current);
}

void init({List<String> additionalArguments}) async {
  sdkDir = defaultSdkDir;
  sdkPackageMeta = PackageMeta.fromDir(sdkDir);
  additionalArguments ??= <String>[];

  testPackageGraph = await bootBasicPackage(
      'testing/test_package', ['css', 'code_in_comments', 'excluded'],
      additionalArguments: additionalArguments);
  testPackageGraphGinormous = await bootBasicPackage(
      'testing/test_package', ['css', 'code_in_commnets', 'excluded'],
      additionalArguments:
          additionalArguments + ['--auto-include-dependencies']);

  testPackageGraphExperiments = await bootBasicPackage(
      'testing/test_package_experiments', [],
      additionalArguments:
          additionalArguments + ['--enable-experiment', 'set-literals']);

  testPackageGraphSmall = await bootBasicPackage(
      'testing/test_package_small', [],
      additionalArguments: additionalArguments);

  testPackageGraphErrors = await bootBasicPackage(
      'testing/test_package_doc_errors',
      ['css', 'code_in_comments', 'excluded'],
      additionalArguments: additionalArguments);
  testPackageGraphSdk = await bootSdkPackage();
}

Future<PackageGraph> bootSdkPackage() async {
  return PackageBuilder(await contextFromArgv(['--input', sdkDir.path]))
      .buildPackageGraph();
}

Future<PackageGraph> bootBasicPackage(
    String dirPath, List<String> excludeLibraries,
    {List<String> additionalArguments}) async {
  Directory dir = Directory(dirPath);
  additionalArguments ??= <String>[];
  return PackageBuilder(await contextFromArgv([
            '--input',
            dir.path,
            '--sdk-dir',
            sdkDir.path,
            '--exclude',
            excludeLibraries.join(','),
            '--allow-tools',
          ] +
          additionalArguments))
      .buildPackageGraph();
}

/// Keeps track of coverage data automatically for any processes run by this
/// [CoverageSubprocessLauncher].  Requires that these be dart processes.
class CoverageSubprocessLauncher extends SubprocessLauncher {
  CoverageSubprocessLauncher(String context, [Map<String, String> environment])
      : super(context, environment) {
    environment ??= {};
    environment['DARTDOC_COVERAGE_DATA'] = tempDir.path;
  }

  static int nextRun = 0;

  /// Set this to true to enable coverage runs.
  static bool get coverageEnabled =>
      Platform.environment.containsKey('COVERAGE_TOKEN');

  /// A list of all coverage results picked up by all launchers.
  static List<Future<Iterable<Map>>> coverageResults = [];

  static Directory _tempDir;
  static Directory get tempDir {
    if (_tempDir == null) {
      if (Platform.environment['DARTDOC_COVERAGE_DATA'] != null) {
        _tempDir = Directory(Platform.environment['DARTDOC_COVERAGE_DATA']);
      } else {
        _tempDir = Directory.systemTemp.createTempSync('dartdoc_coverage_data');
      }
    }
    return _tempDir;
  }

  static String buildNextCoverageFilename() =>
      path.join(tempDir.path, 'dart-cov-${pid}-${nextRun++}.json');

  /// Call once all coverage runs have been generated by calling runStreamed
  /// on all [CoverageSubprocessLaunchers].
  static Future<void> generateCoverageToFile(File outputFile) async {
    if (!coverageEnabled) return Future.value(null);
    var currentCoverageResults = coverageResults;
    coverageResults = [];
    var launcher = SubprocessLauncher('format_coverage');

    /// Wait for all coverage runs to finish.
    await Future.wait(currentCoverageResults);

    return launcher.runStreamed('pub', [
      'run',
      'coverage:format_coverage',
      '--lcov',
      '-v',
      '-b',
      '.',
      '--packages=.packages',
      '--sdk-root=${path.canonicalize(path.join(path.dirname(Platform.executable), '..'))}',
      '--out=${path.canonicalize(outputFile.path)}',
      '--report-on=bin,lib',
      '-i',
      tempDir.path,
    ]);
  }

  @override
  Future<Iterable<Map>> runStreamed(String executable, List<String> arguments,
      {String workingDirectory,
      Map<String, String> environment,
      bool includeParentEnvironment = true,
      void Function(String) perLine}) async {
    environment ??= {};
    assert(
        executable == Platform.executable ||
            executable == Platform.resolvedExecutable,
        'Must use dart executable for tracking coverage');

    Completer<String> portAsString = Completer();
    void parsePortAsString(String line) {
      if (!portAsString.isCompleted && coverageEnabled) {
        Match m = observatoryPortRegexp.matchAsPrefix(line);
        if (m?.group(1) != null) portAsString.complete(m.group(1));
      } else {
        if (perLine != null) perLine(line);
      }
    }

    Completer<Iterable<Map>> coverageResult;

    if (coverageEnabled) {
      coverageResult = Completer();
      // This must be added before awaiting in this method.
      coverageResults.add(coverageResult.future);
      arguments = [
        '--disable-service-auth-codes',
        '--enable-vm-service:0',
        '--pause-isolates-on-exit'
      ]..addAll(arguments);
      if (!environment.containsKey('DARTDOC_COVERAGE_DATA')) {
        environment['DARTDOC_COVERAGE_DATA'] = tempDir.path;
      }
    }

    Future<Iterable<Map>> results = super.runStreamed(executable, arguments,
        environment: environment,
        includeParentEnvironment: includeParentEnvironment,
        workingDirectory: workingDirectory,
        perLine: parsePortAsString);

    if (coverageEnabled) {
      // ignore: unawaited_futures
      super.runStreamed('pub', [
        'run',
        'coverage:collect_coverage',
        '--wait-paused',
        '--resume-isolates',
        '--port=${await portAsString.future}',
        '--out=${buildNextCoverageFilename()}',
      ]).then((r) => coverageResult.complete(r));
    }
    return results;
  }
}

class SubprocessLauncher {
  final String context;
  final Map<String, String> environmentDefaults;

  String get prefix => context.isNotEmpty ? '$context: ' : '';

  // from flutter:dev/tools/dartdoc.dart, modified
  static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
      {String prefix = '', Iterable<String> Function(String line) filter}) {
    assert(prefix != null);
    if (filter == null) filter = (line) => [line];
    return stream
        .transform(utf8.decoder)
        .transform(const LineSplitter())
        .expand(filter)
        .listen((String line) {
      if (line != null) {
        output.write('$prefix$line'.trim());
        output.write('\n');
      }
    }).asFuture();
  }

  SubprocessLauncher(this.context, [Map<String, String> environment])
      : this.environmentDefaults = environment ?? <String, String>{};

  /// A wrapper around start/await process.exitCode that will display the
  /// output of the executable continuously and fail on non-zero exit codes.
  /// It will also parse any valid JSON objects (one per line) it encounters
  /// on stdout/stderr, and return them.  Returns null if no JSON objects
  /// were encountered, or if DRY_RUN is set to 1 in the execution environment.
  ///
  /// Makes running programs in grinder similar to set -ex for bash, even on
  /// Windows (though some of the bashisms will no longer make sense).
  /// TODO(jcollins-g): refactor to return a stream of stderr/stdout lines
  ///                   and their associated JSON objects.
  Future<Iterable<Map>> runStreamed(String executable, List<String> arguments,
      {String workingDirectory,
      Map<String, String> environment,
      bool includeParentEnvironment = true,
      void Function(String) perLine}) async {
    environment ??= {};
    environment.addAll(environmentDefaults);
    List<Map> jsonObjects;

    /// Allow us to pretend we didn't pass the JSON flag in to dartdoc by
    /// printing what dartdoc would have printed without it, yet storing
    /// json objects into [jsonObjects].
    Iterable<String> jsonCallback(String line) {
      if (perLine != null) perLine(line);
      Map result;
      try {
        result = json.decoder.convert(line);
      } catch (FormatException) {
        // ignore
      }
      if (result != null) {
        if (jsonObjects == null) {
          jsonObjects = List();
        }
        jsonObjects.add(result);
        if (result.containsKey('message')) {
          line = result['message'];
        } else if (result.containsKey('data')) {
          line = result['data']['text'];
        }
      }
      return line.split('\n');
    }

    stderr.write('$prefix+ ');
    if (workingDirectory != null) stderr.write('(cd "$workingDirectory" && ');
    if (environment != null) {
      stderr.write(environment.keys.map((String key) {
        if (environment[key].contains(quotables)) {
          return "$key='${environment[key]}'";
        } else {
          return "$key=${environment[key]}";
        }
      }).join(' '));
      stderr.write(' ');
    }
    stderr.write('$executable');
    if (arguments.isNotEmpty) {
      for (String arg in arguments) {
        if (arg.contains(quotables)) {
          stderr.write(" '$arg'");
        } else {
          stderr.write(" $arg");
        }
      }
    }
    if (workingDirectory != null) stderr.write(')');
    stderr.write('\n');

    if (Platform.environment.containsKey('DRY_RUN')) return null;

    String realExecutable = executable;
    final List<String> realArguments = [];
    if (Platform.isLinux) {
      // Use GNU coreutils to force line buffering.  This makes sure that
      // subprocesses that die due to fatal signals do not chop off the
      // last few lines of their output.
      //
      // Dart does not actually do this (seems to flush manually) unless
      // the VM crashes.
      realExecutable = 'stdbuf';
      realArguments.addAll(['-o', 'L', '-e', 'L']);
      realArguments.add(executable);
    }
    realArguments.addAll(arguments);

    Process process = await Process.start(realExecutable, realArguments,
        workingDirectory: workingDirectory,
        environment: environment,
        includeParentEnvironment: includeParentEnvironment);
    Future<void> stdoutFuture = _printStream(process.stdout, stdout,
        prefix: prefix, filter: jsonCallback);
    Future<void> stderrFuture = _printStream(process.stderr, stderr,
        prefix: prefix, filter: jsonCallback);
    await Future.wait([stderrFuture, stdoutFuture, process.exitCode]);

    int exitCode = await process.exitCode;
    if (exitCode != 0) {
      throw ProcessException(executable, arguments,
          "SubprocessLauncher got non-zero exitCode: $exitCode", exitCode);
    }
    return jsonObjects;
  }
}
