// Copyright (c) 2018, 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:io';

import 'package:dwds_test_common/test_sdk_configuration.dart';
import 'package:dwds_test_common/test_sdk_layout.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';

final _webdevBin = p.absolute(p.join('bin', 'webdev.dart'));

class TestRunner {
  late TestSdkConfigurationProvider sdkConfigurationProvider;
  late TestSdkLayout sdkLayout;

  Future<void> setUpAll({bool verbose = false}) async {
    // Generate missing SDK assets if needed.
    sdkConfigurationProvider = TestSdkConfigurationProvider(verbose: verbose);
    sdkLayout = sdkConfigurationProvider.sdkLayout;

    try {
      // Make sure configuration was created correctly.
      final configuration = await sdkConfigurationProvider.configuration;
      configuration.validate();
    } catch (_) {
      tearDownAll();
      rethrow;
    }
  }

  void tearDownAll() {
    sdkConfigurationProvider.dispose();
  }

  Future<TestProcess> runWebDev(
    List<String> args, {
    String? workingDirectory,
  }) async {
    final fullArgs = [_webdevBin, ...args];

    return TestProcess.start(
      sdkLayout.dartPath,
      fullArgs,
      workingDirectory: workingDirectory,
    );
  }

  Future<String> prepareWorkspace() async {
    final exampleDirectory = p.absolute(
      p.join(p.current, '..', 'dwds_test_common', 'fixtures', '_webdev_smoke'),
    );

    final process = await TestProcess.start(
      sdkLayout.dartPath,
      ['pub', 'upgrade'],
      workingDirectory: exampleDirectory,
      environment: getPubEnvironment(),
    );

    await process.shouldExit(0);
    return exampleDirectory;
  }
}

Future checkProcessStdout(TestProcess process, List items) async {
  for (var item in items) {
    if (item is! Matcher) {
      item = contains(item);
    }

    await expectLater(process.stdout, emitsThrough(item));
  }
}

/// Returns an environment map that includes `PUB_ENVIRONMENT`.
///
/// Maintains any existing values for this environment var.
/// Adds a new value that flags this is a bot/test and not human usage.
Map<String, String> getPubEnvironment() {
  final pubEnvironmentKey = 'PUB_ENVIRONMENT';
  var pubEnvironment = Platform.environment[pubEnvironmentKey] ?? '';
  if (pubEnvironment.isNotEmpty) {
    pubEnvironment = '$pubEnvironment;';
  }
  pubEnvironment = '${pubEnvironment}bot.pkg.webdev.test';

  final environment = {'PUB_ENVIRONMENT': pubEnvironment};

  return environment;
}
