// Copyright (c) 2013, 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 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';

import '../command_runner.dart';
import '../lock_file.dart';
import '../log.dart' as log;
import '../package_name.dart';
import '../pubspec.dart';
import '../source/hosted.dart';
import '../source/root.dart';
import '../system_cache.dart';
import '../utils.dart';
import 'result.dart';
import 'type.dart';

/// Unlike [SolveResult], which is the static data describing a resolution,
/// this class contains the mutable state used while generating the report
/// itself.
///
/// It's a report builder.
class SolveReport {
  final SolveType _type;
  // The report will contain "in [_location]" if given.
  final String? _location;
  final Pubspec _rootPubspec;
  final LockFile _previousLockFile;
  final LockFile _newLockFile;
  final SystemCache _cache;
  final bool _dryRun;

  /// If quiet only a single summary line is output.
  final bool _quiet;

  final bool _enforceLockfile;

  /// The available versions of all selected packages from their source.
  ///
  /// An entry here may not include the full list of versions available if the
  /// given package was locked and did not need to be unlocked during the solve.
  ///
  /// Version list will not contain any retracted package versions.
  final Map<String, List<Version>> _availableVersions;

  static const maxAdvisoryFootnotesPerLine = 5;
  final advisoryDisplayHandles = <String>[];

  SolveReport(
    this._type,
    this._location,
    this._rootPubspec,
    this._previousLockFile,
    this._newLockFile,
    this._availableVersions,
    this._cache, {
    required bool dryRun,
    required bool enforceLockfile,
    required bool quiet,
  })  : _dryRun = dryRun,
        _quiet = quiet,
        _enforceLockfile = enforceLockfile;

  /// Displays a report of the results of the version resolution in
  /// [_newLockFile] relative to the [_previousLockFile] file.
  ///
  /// If [summary] is `true` a count of changes and number of
  /// discontinued/retracted packages will be shown at the end of the report.

  Future<void> show({required bool summary}) async {
    final changes = await _reportChanges();
    _checkContentHashesMatchOldLockfile();
    if (summary) await summarize(changes);
  }

  void _checkContentHashesMatchOldLockfile() {
    final issues = <String>[];

    final newPackageNames = _newLockFile.packages.keys.toSet();
    final oldPackageNames = _previousLockFile.packages.keys.toSet();
    // We only care about packages that exist in both new and old lockfile.
    for (final name in newPackageNames.intersection(oldPackageNames)) {
      final newId = _newLockFile.packages[name]!;
      final oldId = _previousLockFile.packages[name]!;

      // We only care about hosted packages
      final newDescription = newId.description;
      final oldDescription = oldId.description;
      if (newDescription is! ResolvedHostedDescription ||
          oldDescription is! ResolvedHostedDescription) {
        continue;
      }

      // We don't care about changes in the hash if the version number changed!
      if (newId.version != oldId.version) {
        continue;
      }

      // Use the cached content-hashes after downloading to ensure that
      // content-hashes from legacy servers gets used.
      final cachedHash = newDescription.sha256;
      assert(cachedHash != null);

      // Ignore cases where the old lockfile doesn't have a content-hash
      final oldHash = oldDescription.sha256;
      if (oldHash == null) {
        continue;
      }

      if (!fixedTimeBytesEquals(cachedHash, oldHash)) {
        issues.add(
          '$name-${newId.version} from "${newDescription.description.url}"',
        );
      }
    }

    if (issues.isNotEmpty) {
      warning('''
The existing content-hash from pubspec.lock doesn't match contents for:
 * ${issues.join('\n * ')}

This indicates one of:
 * The content has changed on the server since you created the pubspec.lock.
 * The pubspec.lock has been corrupted.
${_dryRun || _enforceLockfile ? '' : '\nThe content-hashes in pubspec.lock has been updated.'}

For more information see:
$contentHashesDocumentationUrl
''');
    }
  }

  /// Displays a one-line message summarizing what changes were made (or would
  /// be made) to the lockfile.
  ///
  /// If [_dryRun] or [_enforceLockfile] is true, describes it in terms of what
  /// would be done.
  ///
  /// [type] is the type of version resolution that was run.

  /// If [type] is `SolveType.UPGRADE` it also shows the number of packages that
  /// are not at the latest available version and the number of outdated
  /// packages.
  Future<void> summarize(int changes) async {
    // Count how many dependencies actually changed.
    var dependencies = _newLockFile.packages.keys.toSet();
    dependencies.addAll(_previousLockFile.packages.keys);
    dependencies.remove(_rootPubspec.name);

    var suffix = '';
    final dir = _location;
    if (dir != null) {
      if (dir != '.') {
        suffix = ' in `$dir`';
      }
    }

    if (_quiet) {
      if (_dryRun) {
        log.message('Would get dependencies$suffix.');
      } else if (_enforceLockfile) {
        if (changes == 0) {
          log.message('Got dependencies$suffix.');
        }
      } else {
        log.message('Got dependencies$suffix.');
      }
    } else {
      if (_dryRun) {
        if (changes == 0) {
          log.message('No dependencies would change$suffix.');
        } else if (changes == 1) {
          log.message('Would change $changes dependency$suffix.');
        } else {
          log.message('Would change $changes dependencies$suffix.');
        }
      } else if (_enforceLockfile) {
        if (changes == 0) {
          log.message('Got dependencies$suffix!');
        } else if (changes == 1) {
          log.message('Would change $changes dependency$suffix.');
        } else {
          log.message('Would change $changes dependencies$suffix.');
        }
      } else {
        if (changes == 0) {
          if (_type == SolveType.get) {
            log.message('Got dependencies$suffix!');
          } else {
            log.message('No dependencies changed$suffix.');
          }
        } else if (changes == 1) {
          log.message('Changed $changes dependency$suffix!');
        } else {
          log.message('Changed $changes dependencies$suffix!');
        }
      }
      await reportDiscontinued();
      reportAdvisories();
      reportOutdated();
    }
  }

  /// Displays a report of all of the previous and current dependencies and
  /// how they have changed.
  ///
  /// Returns the number of changes.
  Future<int> _reportChanges() async {
    final output = StringBuffer();
    // Show the new set of dependencies ordered by name.
    var names = _newLockFile.packages.keys.toList();
    names.remove(_rootPubspec.name);
    names.sort();
    var changes = 0;
    for (final name in names) {
      changes += await _reportPackage(name, output) ? 1 : 0;
    }
    // Show any removed ones.
    var removed = _previousLockFile.packages.keys.toSet();
    removed.removeAll(names);
    removed.remove(_rootPubspec.name); // Never consider root.
    if (removed.isNotEmpty) {
      output.writeln('These packages are no longer being depended on:');
      for (var name in ordered(removed)) {
        await _reportPackage(name, output, alwaysShow: true);
        changes += 1;
      }
    }

    message(output.toString());
    return changes;
  }

  /// Displays a single-line message, number of discontinued packages
  /// if discontinued packages are detected.
  Future<void> reportDiscontinued() async {
    var numDiscontinued = 0;
    for (var id in _newLockFile.packages.values) {
      if (id.description is RootDescription) continue;
      final status = await id.source
          .status(id.toRef(), id.version, _cache, maxAge: Duration(days: 3));
      if (status.isDiscontinued &&
          (_rootPubspec.dependencyType(id.name) == DependencyType.direct ||
              _rootPubspec.dependencyType(id.name) == DependencyType.dev)) {
        numDiscontinued++;
      }
    }
    if (numDiscontinued > 0) {
      if (numDiscontinued == 1) {
        message('1 package is discontinued.');
      } else {
        message('$numDiscontinued packages are discontinued.');
      }
    }
  }

  /// Displays a two-line message, number of outdated packages and an
  /// instruction to run `pub outdated` if outdated packages are detected.
  void reportOutdated() {
    final outdatedPackagesCount = _newLockFile.packages.values.where((id) {
      final versions = _availableVersions[id.name]!;
      // A version is counted:
      // - if there is a newer version which is not a pre-release and current
      // version is also not a pre-release or,
      // - if the current version is pre-release then any upgraded version is
      // considered.
      return versions.any(
        (v) => v > id.version && (id.version.isPreRelease || !v.isPreRelease),
      );
    }).length;

    if (outdatedPackagesCount > 0) {
      String packageCountString;
      if (outdatedPackagesCount == 1) {
        packageCountString = '1 package has';
      } else {
        packageCountString = '$outdatedPackagesCount packages have';
      }
      message('$packageCountString newer versions incompatible with '
          'dependency constraints.\nTry `$topLevelProgram pub outdated` for more information.');
    }
  }

  void reportAdvisories() {
    if (advisoryDisplayHandles.isNotEmpty) {
      message('Dependencies are affected by security advisories:');
      for (var footnote = 0;
          footnote < advisoryDisplayHandles.length;
          footnote++) {
        message(
          '  [^$footnote]: ${advisoryDisplayHandles[footnote]}',
        );
      }
    }
  }

  static DependencyType dependencyType(LockFile lockFile, String name) =>
      lockFile.mainDependencies.contains(name)
          ? DependencyType.direct
          : lockFile.devDependencies.contains(name)
              ? DependencyType.dev
              : DependencyType.none;

  String? _constructAdvisoriesMessage(
    List<int> footnotes,
    bool advisoriesTruncated,
  ) {
    if (footnotes.isNotEmpty) {
      final advisoryString = footnotes.length == 1 ? 'advisory' : 'advisories';
      final buffer = StringBuffer('affected by $advisoryString: ');
      buffer.write('[^${footnotes.first}]');
      for (final footnote in footnotes.getRange(1, footnotes.length)) {
        buffer.write(', [^$footnote]');
      }

      if (advisoriesTruncated) {
        buffer.write(', ...');
      }
      return buffer.toString();
    }
    return null;
  }

  /// Reports the results of the upgrade on the package named [name].
  ///
  /// If [alwaysShow] is true, the package is reported even if it didn't change,
  /// regardless of [_type]. If [highlightOverride] is true (or absent), writes
  /// "(override)" next to overridden packages.
  ///
  /// Returns true if the package had changed.
  Future<bool> _reportPackage(
    String name,
    StringBuffer output, {
    bool alwaysShow = false,
  }) async {
    var newId = _newLockFile.packages[name];
    var oldId = _previousLockFile.packages[name];
    var id = newId ?? oldId!;

    var isOverridden = _rootPubspec.dependencyOverrides.containsKey(id.name);

    // If the package was previously a dependency but the dependency has
    // changed in some way.
    var changed = false;

    // If the dependency was added or removed.
    var addedOrRemoved = false;

    // Show a one-character "icon" describing the change. They are:
    //
    //     ! The package is being overridden.
    //     - The package was removed.
    //     + The package was added.
    //     > The package was upgraded from a lower version.
    //     < The package was downgraded from a higher version.
    //     ~ Package contents has changed, but not the version number.
    //     * Any other change between the old and new package.
    String icon;
    if (isOverridden) {
      icon = log.magenta('! ');
    } else if (newId == null) {
      icon = log.red('- ');
      addedOrRemoved = true;
    } else if (oldId == null) {
      icon = log.green('+ ');
      addedOrRemoved = true;
    } else if (oldId.description.description != newId.description.description) {
      // Eg. a changed source in pubspec.yaml.
      icon = log.cyan('* ');
      changed = true;
    } else if (oldId.version < newId.version) {
      icon = log.green('> ');
      changed = true;
    } else if (oldId.version > newId.version) {
      icon = log.cyan('< ');
      changed = true;
    } else if (oldId.description != newId.description) {
      // Eg. a changed hash or revision.
      icon = log.cyan('~ ');
      changed = true;
    } else {
      // Unchanged.
      icon = '  ';
    }
    String? message;
    // See if there are any newer versions of the package that we were
    // unable to upgrade to.
    if (newId != null && _type != SolveType.downgrade) {
      var versions = _availableVersions[newId.name]!;

      var newerStable = false;
      var newerUnstable = false;

      for (var version in versions) {
        if (version > newId.version) {
          if (version.isPreRelease) {
            newerUnstable = true;
          } else {
            newerStable = true;
          }
        }
      }
      final status = await id.source.status(
        id.toRef(),
        id.version,
        _cache,
        maxAge: Duration(days: 3),
      );

      final notes = <String>[];

      final advisories = await id.source.getAdvisoriesForPackageVersion(
        id,
        _cache,
        Duration(days: 3),
      );

      if (advisories != null && advisories.isNotEmpty) {
        final advisoryFootnotes = <int>[];
        final reportedAdvisories = advisories
            .where(
              (adv) => _rootPubspec.ignoredAdvisories.intersection({
                ...adv.aliases,
                adv.id,
              }).isEmpty,
            )
            .take(maxAdvisoryFootnotesPerLine);
        for (final adv in reportedAdvisories) {
          advisoryFootnotes.add(advisoryDisplayHandles.length);
          advisoryDisplayHandles.add(adv.displayHandle);
        }

        final advisoriesMessage = _constructAdvisoriesMessage(
          advisoryFootnotes,
          advisories.length > maxAdvisoryFootnotesPerLine,
        );

        if (advisoriesMessage != null) {
          notes.add(advisoriesMessage);
        }
      }
      if (status.isRetracted) {
        if (newerStable) {
          notes.add(
            'retracted, ${maxAll(versions, Version.prioritize)} available',
          );
        } else if (newId.version.isPreRelease && newerUnstable) {
          notes.add(
            'retracted, ${maxAll(versions)} available',
          );
        } else {
          notes.add(
            'retracted',
          );
        }
      } else if (status.isDiscontinued &&
          [DependencyType.direct, DependencyType.dev]
              .contains(_rootPubspec.dependencyType(name))) {
        if (status.discontinuedReplacedBy == null) {
          notes.add(
            'discontinued',
          );
        } else {
          notes.add(
            'discontinued replaced by ${status.discontinuedReplacedBy}',
          );
        }
      } else if (newerStable) {
        // If there are newer stable versions, only show those.
        notes.add(
          '${maxAll(versions, Version.prioritize)} available',
        );
      } else if (
          // Only show newer prereleases for versions where a prerelease is
          // already chosen.
          newId.version.isPreRelease && newerUnstable) {
        notes.add(
          '${maxAll(versions)} available',
        );
      }

      message = notes.isEmpty ? null : '(${notes.join(', ')})';
    }

    final oldDependencyType = dependencyType(_previousLockFile, name);
    final newDependencyType = dependencyType(_newLockFile, name);

    var dependencyTypeChanged = oldId != null &&
        newId != null &&
        oldDependencyType != newDependencyType;

    if (!(alwaysShow ||
        changed ||
        addedOrRemoved ||
        dependencyTypeChanged ||
        message != null ||
        isOverridden)) {
      return changed || addedOrRemoved || dependencyTypeChanged;
    }

    output.write(icon);
    output.write(log.bold(id.name));
    output.write(' ');
    _writeId(id, output);

    // If the package was upgraded, show what it was upgraded from.
    if (changed) {
      output.write(' (was ');
      _writeId(oldId!, output);
      output.write(')');
    }

    if (dependencyTypeChanged) {
      if (dependencyTypeChanged) {
        output.write(' (from ');

        _writeDependencyType(oldDependencyType, output);
        output.write(' dependency to ');

        _writeDependencyType(newDependencyType, output);
        output.write(' dependency)');
      }
    }

    // Highlight overridden packages.
    if (isOverridden) {
      final location = _location;
      final overrideLocation =
          location != null && _rootPubspec.dependencyOverridesFromOverridesFile
              ? ' in ${p.join(location, Pubspec.pubspecOverridesFilename)}'
              : '';
      output.write(' ${log.magenta('(overridden$overrideLocation)')}');
    }

    if (message != null) output.write(' ${log.cyan(message)}');

    output.writeln();
    return changed || addedOrRemoved || dependencyTypeChanged;
  }

  /// Writes a terse description of [id] (not including its name) to the output.
  void _writeId(PackageId id, StringBuffer output) {
    output.write(id.version);

    if (id.source != _cache.defaultSource) {
      var description = id.description.format();
      output.write(' from ${id.source} $description');
    }
  }

  void _writeDependencyType(DependencyType t, StringBuffer output) {
    output.write(
      log.bold(
        switch (t) {
          DependencyType.direct => 'direct',
          DependencyType.dev => 'dev',
          DependencyType.none => 'transitive',
        },
      ),
    );
  }

  void warning(String message) {
    if (_quiet) {
      log.fine(message);
    } else {
      log.warning(message);
    }
  }

  void message(String message) {
    if (_quiet) {
      log.fine(message);
    } else {
      log.message(message);
    }
  }
}
