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

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

import 'package:file/file.dart';
import 'package:http/http.dart' as http;
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';

import 'common/core.dart';
import 'common/package_looping_command.dart';
import 'common/process_runner.dart';
import 'common/pub_version_finder.dart';
import 'common/repository_package.dart';

/// A command to check that packages are publishable via 'dart publish'.
class PublishCheckCommand extends PackageLoopingCommand {
  /// Creates an instance of the publish command.
  PublishCheckCommand(
    Directory packagesDir, {
    ProcessRunner processRunner = const ProcessRunner(),
    Platform platform = const LocalPlatform(),
    http.Client? httpClient,
  })  : _pubVersionFinder =
            PubVersionFinder(httpClient: httpClient ?? http.Client()),
        super(packagesDir, processRunner: processRunner, platform: platform) {
    argParser.addFlag(
      _allowPrereleaseFlag,
      help: 'Allows the pre-release SDK warning to pass.\n'
          'When enabled, a pub warning, which asks to publish the package as a pre-release version when '
          'the SDK constraint is a pre-release version, is ignored.',
      defaultsTo: false,
    );
    argParser.addFlag(_machineFlag,
        help: 'Switch outputs to a machine readable JSON. \n'
            'The JSON contains a "status" field indicating the final status of the command, the possible values are:\n'
            '    $_statusNeedsPublish: There is at least one package need to be published. They also passed all publish checks.\n'
            '    $_statusMessageNoPublish: There are no packages needs to be published. Either no pubspec change detected or all versions have already been published.\n'
            '    $_statusMessageError: Some error has occurred.',
        defaultsTo: false,
        negatable: true);
  }

  static const String _allowPrereleaseFlag = 'allow-pre-release';
  static const String _machineFlag = 'machine';
  static const String _statusNeedsPublish = 'needs-publish';
  static const String _statusMessageNoPublish = 'no-publish';
  static const String _statusMessageError = 'error';
  static const String _statusKey = 'status';
  static const String _humanMessageKey = 'humanMessage';

  @override
  final String name = 'publish-check';

  @override
  final String description =
      'Checks to make sure that a plugin *could* be published.';

  final PubVersionFinder _pubVersionFinder;

  /// The overall result of the run for machine-readable output. This is the
  /// highest value that occurs during the run.
  _PublishCheckResult _overallResult = _PublishCheckResult.nothingToPublish;

  @override
  bool get captureOutput => getBoolArg(_machineFlag);

  @override
  Future<void> initializeRun() async {
    _overallResult = _PublishCheckResult.nothingToPublish;
  }

  @override
  Future<PackageResult> runForPackage(RepositoryPackage package) async {
    _PublishCheckResult? result = await _passesPublishCheck(package);
    if (result == null) {
      return PackageResult.skip('Package is marked as unpublishable.');
    }
    if (!_passesAuthorsCheck(package)) {
      _printImportantStatusMessage(
          'No AUTHORS file found. Packages must include an AUTHORS file.',
          isError: true);
      result = _PublishCheckResult.error;
    }

    if (result.index > _overallResult.index) {
      _overallResult = result;
    }
    return result == _PublishCheckResult.error
        ? PackageResult.fail()
        : PackageResult.success();
  }

  @override
  Future<void> completeRun() async {
    _pubVersionFinder.httpClient.close();
  }

  @override
  Future<void> handleCapturedOutput(List<String> output) async {
    final Map<String, dynamic> machineOutput = <String, dynamic>{
      _statusKey: _statusStringForResult(_overallResult),
      _humanMessageKey: output,
    };

    print(const JsonEncoder.withIndent('  ').convert(machineOutput));
  }

  String _statusStringForResult(_PublishCheckResult result) {
    switch (result) {
      case _PublishCheckResult.nothingToPublish:
        return _statusMessageNoPublish;
      case _PublishCheckResult.needsPublishing:
        return _statusNeedsPublish;
      case _PublishCheckResult.error:
        return _statusMessageError;
    }
  }

  Pubspec? _tryParsePubspec(RepositoryPackage package) {
    final File pubspecFile = package.pubspecFile;

    try {
      return Pubspec.parse(pubspecFile.readAsStringSync());
    } on Exception catch (exception) {
      print(
        'Failed to parse `pubspec.yaml` at ${pubspecFile.path}: $exception}',
      );
      return null;
    }
  }

  Future<bool> _hasValidPublishCheckRun(RepositoryPackage package) async {
    print('Running pub publish --dry-run:');
    final io.Process process = await processRunner.start(
      flutterCommand,
      <String>['pub', 'publish', '--', '--dry-run'],
      workingDirectory: package.directory,
    );

    final StringBuffer outputBuffer = StringBuffer();

    final Completer<void> stdOutCompleter = Completer<void>();
    process.stdout.listen(
      (List<int> event) {
        final String output = String.fromCharCodes(event);
        if (output.isNotEmpty) {
          print(output);
          outputBuffer.write(output);
        }
      },
      onDone: () => stdOutCompleter.complete(),
    );

    final Completer<void> stdInCompleter = Completer<void>();
    process.stderr.listen(
      (List<int> event) {
        final String output = String.fromCharCodes(event);
        if (output.isNotEmpty) {
          // The final result is always printed on stderr, whether success or
          // failure.
          final bool isError = !output.contains('has 0 warnings');
          _printImportantStatusMessage(output, isError: isError);
          outputBuffer.write(output);
        }
      },
      onDone: () => stdInCompleter.complete(),
    );

    if (await process.exitCode == 0) {
      return true;
    }

    if (!getBoolArg(_allowPrereleaseFlag)) {
      return false;
    }

    await stdOutCompleter.future;
    await stdInCompleter.future;

    final String output = outputBuffer.toString();
    return output.contains('Package has 1 warning') &&
        output.contains(
            'Packages with an SDK constraint on a pre-release of the Dart SDK should themselves be published as a pre-release version.');
  }

  /// Returns the result of the publish check, or null if the package is marked
  /// as unpublishable.
  Future<_PublishCheckResult?> _passesPublishCheck(
      RepositoryPackage package) async {
    final String packageName = package.directory.basename;
    final Pubspec? pubspec = _tryParsePubspec(package);
    if (pubspec == null) {
      print('No valid pubspec found.');
      return _PublishCheckResult.error;
    } else if (pubspec.publishTo == 'none') {
      return null;
    }

    final Version? version = pubspec.version;
    final _PublishCheckResult alreadyPublishedResult =
        await _checkPublishingStatus(
            packageName: packageName, version: version);
    if (alreadyPublishedResult == _PublishCheckResult.nothingToPublish) {
      print(
          'Package $packageName version: $version has already be published on pub.');
      return alreadyPublishedResult;
    } else if (alreadyPublishedResult == _PublishCheckResult.error) {
      print('Check pub version failed $packageName');
      return _PublishCheckResult.error;
    }

    if (await _hasValidPublishCheckRun(package)) {
      print('Package $packageName is able to be published.');
      return _PublishCheckResult.needsPublishing;
    } else {
      print('Unable to publish $packageName');
      return _PublishCheckResult.error;
    }
  }

  // Check if `packageName` already has `version` published on pub.
  Future<_PublishCheckResult> _checkPublishingStatus(
      {required String packageName, required Version? version}) async {
    final PubVersionFinderResponse pubVersionFinderResponse =
        await _pubVersionFinder.getPackageVersion(packageName: packageName);
    switch (pubVersionFinderResponse.result) {
      case PubVersionFinderResult.success:
        return pubVersionFinderResponse.versions.contains(version)
            ? _PublishCheckResult.nothingToPublish
            : _PublishCheckResult.needsPublishing;
      case PubVersionFinderResult.fail:
        print('''
Error fetching version on pub for $packageName.
HTTP Status ${pubVersionFinderResponse.httpResponse.statusCode}
HTTP response: ${pubVersionFinderResponse.httpResponse.body}
''');
        return _PublishCheckResult.error;
      case PubVersionFinderResult.noPackageFound:
        return _PublishCheckResult.needsPublishing;
    }
  }

  bool _passesAuthorsCheck(RepositoryPackage package) {
    final List<String> pathComponents =
        package.directory.fileSystem.path.split(package.directory.path);
    if (pathComponents.contains('third_party')) {
      // Third-party packages aren't required to have an AUTHORS file.
      return true;
    }
    return package.directory.childFile('AUTHORS').existsSync();
  }

  void _printImportantStatusMessage(String message, {required bool isError}) {
    final String statusMessage = '${isError ? 'ERROR' : 'SUCCESS'}: $message';
    if (getBoolArg(_machineFlag)) {
      print(statusMessage);
    } else {
      if (isError) {
        printError(statusMessage);
      } else {
        printSuccess(statusMessage);
      }
    }
  }
}

/// Possible outcomes of of a publishing check.
enum _PublishCheckResult {
  nothingToPublish,
  needsPublishing,
  error,
}
