// 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' show Directory;

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:build_daemon/client.dart';
import 'package:build_daemon/data/build_status.dart';
import 'package:build_daemon/data/build_target.dart';
import 'package:build_daemon/data/server_log.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:logging/logging.dart' as logging;

import '../daemon_client.dart';
import '../logging.dart';
import '../pubspec.dart';
import 'configuration.dart';
import 'shared.dart';

/// Command to execute pub run build_runner build.
class BuildCommand extends Command<int> {
  @override
  final argParser = ArgParser(usageLineLength: lineLength);

  @override
  final name = 'build';

  @override
  final description = 'Run builders to build a package.';

  BuildCommand() {
    addSharedArgs(argParser, outputDefault: 'web:build');
  }

  @override
  Future<int> run() async {
    final extraArgs = argResults?.rest ?? [];
    final unsupported = extraArgs.where((arg) => !arg.startsWith('-')).toList();
    if (unsupported.isNotEmpty) {
      throw UsageException(
        'Arguments were provided that are not supported: '
        '"${unsupported.join(' ')}".',
        argParser.usage,
      );
    }
    final validExtraArgs = extraArgs
        .where((arg) => arg.startsWith('-'))
        .toList();

    final configuration = Configuration.fromArgs(argResults);
    configureLogWriter(configuration.verbose);

    List<String> arguments;
    try {
      await validatePubspecLock(configuration);
      arguments = buildRunnerArgs(configuration)..addAll(validExtraArgs);
    } on PackageException catch (e) {
      logWriter(
        logging.Level.SEVERE,
        'Pubspec errors: ',
        error: '${e.details}',
      );
      rethrow;
    }

    try {
      logWriter(logging.Level.INFO, 'Connecting to the build daemon...');
      final client = await connectClient(Directory.current.path, arguments, (
        serverLog,
      ) {
        logWriter(
          toLoggingLevel(serverLog.level),
          serverLog.message,
          error: serverLog.error,
          loggerName: serverLog.loggerName,
          stackTrace: serverLog.stackTrace,
        );
      });
      OutputLocation? outputLocation;
      final outputInput = configuration.outputInput;
      if (configuration.outputPath != null) {
        outputLocation = OutputLocation(
          (b) => b
            ..output = configuration.outputPath
            ..useSymlinks = false
            ..hoist = outputInput != null && outputInput.isNotEmpty,
        );
      }
      client.registerBuildTarget(
        DefaultBuildTarget(
          (b) => b
            ..target = configuration.outputInput
            ..outputLocation = outputLocation?.toBuilder()
            ..reportChangedAssets = true,
        ),
      );
      client.startBuild();
      var exitCode = 0;
      var gotBuildStart = false;
      await for (final result in client.buildResults) {
        final targetResult = result.results.firstWhereOrNull(
          (buildResult) => buildResult.target == configuration.outputInput,
        );
        if (targetResult == null) continue;
        // We ignore any builds that happen before we get a `started` event,
        // because those could be stale (from some other client).
        gotBuildStart =
            gotBuildStart || targetResult.status == BuildStatus.started;
        if (!gotBuildStart) continue;

        // Shouldn't happen, but being a bit defensive here.
        if (targetResult.status == BuildStatus.started) continue;

        if (targetResult.status == BuildStatus.failed) {
          exitCode = 1;
        }

        final error = targetResult.error ?? '';
        if (error.isNotEmpty) {
          logWriter(logging.Level.SEVERE, error);
        }
        break;
      }
      await client.close();
      return exitCode;
    } on OptionsSkew catch (_) {
      logWriter(
        logging.Level.SEVERE,
        'Incompatible options with current running build daemon.\n\n'
        'Please stop other WebDev instances running in this directory '
        'before starting a new instance with these options.\n\n',
      );
      return 1;
    }
  }
}
