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

import 'package:pub_semver/pub_semver.dart';

import '../command_runner.dart';
import '../entrypoint.dart';
import '../flutter_releases.dart';
import '../io.dart';
import '../package.dart';
import '../package_name.dart';
import '../pubspec_utils.dart';
import '../solver.dart';
import '../source/hosted.dart';
import '../system_cache.dart';
import 'incompatibility.dart';
import 'incompatibility_cause.dart';

/// Looks through the root-[incompatibility] of a solve-failure and tries to see
/// if the conflict could resolved by any of the following suggestions:
/// * An update of the current SDK.
/// * Any single change to a package constraint.
/// * Removing the bounds on all constraints, changing less than 5 dependencies.
/// * Running `pub upgrade --major versions`.
///
/// Returns a formatted list of suggestions, or the empty String if no
/// suggestions were found.
Future<String?> suggestResolutionAlternatives(
  Entrypoint entrypoint,
  SolveType type,
  Incompatibility incompatibility,
  Iterable<String> unlock,
  SystemCache cache,
) async {
  if (entrypoint.workspaceRoot.workspaceChildren.isNotEmpty) {
    // TODO(https://github.com/dart-lang/pub/issues/4227): handle workspaces.
    return null;
  }
  final resolutionContext = _ResolutionContext(
    entrypoint: entrypoint,
    type: type,
    cache: cache,
    unlock: unlock,
  );

  final visited = <String>{};
  final stopwatch = Stopwatch()..start();
  final suggestions = <_ResolutionSuggestion>[];
  void addSuggestionIfPresent(_ResolutionSuggestion? suggestion) {
    if (suggestion != null) suggestions.add(suggestion);
  }

  for (final externalIncompatibility
      in incompatibility.externalIncompatibilities) {
    if (stopwatch.elapsed > const Duration(seconds: 3)) {
      // Never spend more than 3 seconds computing suggestions.
      break;
    }
    final cause = externalIncompatibility.cause;
    if (cause is SdkIncompatibilityCause) {
      addSuggestionIfPresent(await resolutionContext.suggestSdkUpdate(cause));
    } else {
      for (final term in externalIncompatibility.terms) {
        final name = term.package.name;

        if (!visited.add(name)) {
          continue;
        }
        addSuggestionIfPresent(
          await resolutionContext.suggestSinglePackageUpdate(name),
        );
      }
    }
  }
  if (suggestions.isEmpty) {
    addSuggestionIfPresent(
      await resolutionContext.suggestUnlockingAll(stripLowerBound: true) ??
          await resolutionContext.suggestUnlockingAll(stripLowerBound: false),
    );
  }

  if (suggestions.isEmpty) return null;
  final tryOne =
      suggestions.length == 1
          ? 'You can try the following suggestion to make the pubspec resolve:'
          : 'You can try one of the following suggestions '
              'to make the pubspec resolve:';

  suggestions.sort((a, b) => a.priority.compareTo(b.priority));

  return '\n$tryOne\n'
      '${suggestions.take(5).map((e) => e.suggestion).join('\n')}';
}

class _ResolutionSuggestion {
  final String suggestion;
  final int priority;
  _ResolutionSuggestion(this.suggestion, {this.priority = 0});
}

String packageAddDescription(Entrypoint entrypoint, PackageId id) {
  final name = id.name;
  final isDev = entrypoint.workspaceRoot.pubspec.devDependencies.containsKey(
    name,
  );
  final resolvedDescription = id.description;
  final String descriptor;
  final d = resolvedDescription.description.serializeForPubspec(
    containingDir:
        Directory
            .current
            .path, // The add command will resolve file names relative to CWD.
    // This currently should have no implications as we don't create suggestions
    // for path-packages.
    languageVersion: entrypoint.workspaceRoot.pubspec.languageVersion,
  );
  if (d == null) {
    descriptor = VersionConstraint.compatibleWith(id.version).toString();
  } else {
    descriptor = json.encode({
      'version': VersionConstraint.compatibleWith(id.version).toString(),
      id.source.name: d,
    });
  }

  final devPart = isDev ? 'dev:' : '';
  return '$devPart$name:${escapeShellArgument(descriptor)}';
}

class _ResolutionContext {
  final Entrypoint entrypoint;
  final SolveType type;
  final Iterable<String> unlock;
  final SystemCache cache;
  _ResolutionContext({
    required this.entrypoint,
    required this.type,
    required this.cache,
    required this.unlock,
  });

  /// If [cause] mentions an sdk, attempt resolving using another released
  /// version of Flutter/Dart. Return that as a suggestion if found.
  Future<_ResolutionSuggestion?> suggestSdkUpdate(
    SdkIncompatibilityCause cause,
  ) async {
    final sdkName = cause.sdk.identifier;
    if (!(sdkName == 'dart' || (sdkName == 'flutter' && runningFromFlutter))) {
      // Only make sdk upgrade suggestions for Flutter and Dart.
      return null;
    }

    final constraint = cause.constraint;
    if (constraint == null) return null;

    // Find the most relevant Flutter release fulfilling the constraint.
    final bestRelease = await inferBestFlutterRelease({
      cause.sdk.identifier: constraint,
    });
    if (bestRelease == null) return null;
    final result = await _tryResolve(
      entrypoint.workspaceRoot,
      sdkOverrides: {
        'dart': bestRelease.dartVersion,
        'flutter': bestRelease.flutterVersion,
      },
    );
    if (result == null) {
      return null;
    }
    return _ResolutionSuggestion(
      runningFromFlutter
          ? '* Try using the Flutter SDK version: '
              '${bestRelease.flutterVersion}. '
          :
          // Here we assume that any Dart version included in a Flutter
          // release can also be found as a released Dart SDK.
          '* Try using the Dart SDK version: ${bestRelease.dartVersion}. See https://dart.dev/get-dart.',
    );
  }

  /// Attempt another resolution with a relaxed constraint on [name]. If that
  /// resolves, suggest upgrading to that version.
  Future<_ResolutionSuggestion?> suggestSinglePackageUpdate(String name) async {
    // TODO(https://github.com/dart-lang/pub/issues/4127): This should
    // operate on all packages in workspace.
    final originalRange =
        entrypoint.workspaceRoot.dependencies[name] ??
        entrypoint.workspaceRoot.devDependencies[name];
    if (originalRange == null ||
        originalRange.description is! HostedDescription) {
      // We can only relax constraints on hosted dependencies.
      return null;
    }
    final originalConstraint = originalRange.constraint;
    final relaxedPubspec = stripVersionBounds(
      entrypoint.workspaceRoot.pubspec,
      stripOnly: [name],
      stripLowerBound: true,
    );

    final result = await _tryResolve(
      Package(
        relaxedPubspec,
        entrypoint.workspaceRoot.dir,
        entrypoint.workspaceRoot.workspaceChildren,
      ),
    );
    if (result == null) {
      return null;
    }
    final resolvingPackage = result.packages.firstWhere((p) => p.name == name);

    final addDescription = packageAddDescription(entrypoint, resolvingPackage);

    var priority = 1;
    var suggestion =
        '* Try updating your constraint on $name: '
        '$topLevelProgram pub add $addDescription';
    if (originalConstraint is VersionRange) {
      final min = originalConstraint.min;
      if (min != null) {
        if (resolvingPackage.version < min) {
          priority = 3;
          suggestion =
              '* Consider downgrading your constraint on $name: '
              '$topLevelProgram pub add $addDescription';
        } else {
          priority = 2;
          suggestion =
              '* Try upgrading your constraint on $name: '
              '$topLevelProgram pub add $addDescription';
        }
      }
    }

    return _ResolutionSuggestion(suggestion, priority: priority);
  }

  /// Attempt resolving with all version constraints relaxed. If that resolves,
  /// return a corresponding suggestion to update.
  Future<_ResolutionSuggestion?> suggestUnlockingAll({
    required bool stripLowerBound,
  }) async {
    final originalPubspec = entrypoint.workspaceRoot.pubspec;
    final relaxedPubspec = stripVersionBounds(
      originalPubspec,
      stripLowerBound: stripLowerBound,
    );

    final result = await _tryResolve(
      Package(
        relaxedPubspec,
        entrypoint.workspaceRoot.dir,
        entrypoint.workspaceRoot.workspaceChildren,
      ),
    );
    if (result == null) {
      return null;
    }
    final updatedPackageVersions = <PackageId>[];
    for (final id in result.packages) {
      final originalConstraint =
          (originalPubspec.dependencies[id.name] ??
                  originalPubspec.devDependencies[id.name])
              ?.constraint;
      if (originalConstraint != null) {
        updatedPackageVersions.add(id);
      }
    }
    if (stripLowerBound && updatedPackageVersions.length > 5) {
      // Too complex, don't suggest.
      return null;
    }
    if (stripLowerBound) {
      updatedPackageVersions.sort((a, b) => a.name.compareTo(b.name));
      final formattedConstraints = updatedPackageVersions
          .map((e) => packageAddDescription(entrypoint, e))
          .join(' ');
      return _ResolutionSuggestion(
        '* Try updating the following constraints: '
        '$topLevelProgram pub add $formattedConstraints',
        priority: 4,
      );
    } else {
      return _ResolutionSuggestion(
        '* Try an upgrade of your constraints: '
        '$topLevelProgram pub upgrade --major-versions',
        priority: 4,
      );
    }
  }

  /// Attempt resolving
  Future<SolveResult?> _tryResolve(
    Package package, {
    Map<String, Version> sdkOverrides = const {},
  }) async {
    try {
      return await resolveVersions(
        type,
        cache,
        package,
        sdkOverrides: sdkOverrides,
        lockFile: entrypoint.lockFile,
        unlock: unlock,
      );
    } on SolveFailure {
      return null;
    }
  }
}
