// Copyright (c) 2017, 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:collection/collection.dart';
import 'package:pub_semver/pub_semver.dart';

import 'package.dart';
import 'source.dart';
import 'source/hosted.dart';
import 'utils.dart';

/// The equality to use when comparing the feature sets of two package names.
const _featureEquality = MapEquality<String, FeatureDependency>();

/// The base class of [PackageRef], [PackageId], and [PackageRange].
abstract class PackageName {
  /// The name of the package being identified.
  final String name;

  /// The [Source] used to look up this package.
  ///
  /// If this is a root package, this will be `null`.
  final Source? source;

  /// The metadata used by the package's [source] to identify and locate it.
  ///
  /// It contains whatever [Source]-specific data it needs to be able to get
  /// the package. For example, the description of a git sourced package might
  /// by the URL "git://github.com/dart/uilib.git".
  final dynamic description;

  /// Whether this package is the root package.
  bool get isRoot => source == null;

  PackageName._(this.name, this.source, this.description);

  /// Returns a [PackageRef] with this one's [name], [source], and
  /// [description].
  PackageRef toRef() => PackageRef(name, source, description);

  /// Returns a [PackageRange] for this package with the given version constraint.
  PackageRange withConstraint(VersionConstraint constraint) =>
      PackageRange(name, source, constraint, description);

  /// Returns whether this refers to the same package as [other].
  ///
  /// This doesn't compare any constraint information; it's equivalent to
  /// `this.toRef() == other.toRef()`.
  bool samePackage(PackageName other) {
    if (other.name != name) return false;
    var thisSource = source;
    if (thisSource == null) return other.source == null;

    return other.source == thisSource &&
        thisSource.descriptionsEqual(description, other.description);
  }

  @override
  bool operator ==(Object other) =>
      throw UnimplementedError('Subclass should implement ==');

  @override
  int get hashCode {
    var thisSource = source;
    if (thisSource == null) return name.hashCode;
    return name.hashCode ^
        thisSource.hashCode ^
        thisSource.hashDescription(description);
  }

  /// Returns a string representation of this package name.
  ///
  /// If [detail] is passed, it controls exactly which details are included.
  @override
  String toString([PackageDetail? detail]);
}

/// A reference to a [Package], but not any particular version(s) of it.
class PackageRef extends PackageName {
  /// Creates a reference to a package with the given [name], [source], and
  /// [description].
  ///
  /// Since an ID's description is an implementation detail of its source, this
  /// should generally not be called outside of [Source] subclasses. A reference
  /// can be obtained from a user-supplied description using [Source.parseRef].
  PackageRef(String name, Source? source, description)
      : super._(name, source, description);

  /// Creates a reference to the given root package.
  PackageRef.root(Package package) : super._(package.name, null, package.name);

  @override
  String toString([PackageDetail? detail]) {
    detail ??= PackageDetail.defaults;
    if (isRoot) return name;

    var buffer = StringBuffer(name);
    if (detail.showSource ?? source is! HostedSource) {
      buffer.write(' from $source');
      if (detail.showDescription) {
        buffer.write(' ${source!.formatDescription(description)}');
      }
    }

    return buffer.toString();
  }

  @override
  bool operator ==(other) => other is PackageRef && samePackage(other);

  @override
  int get hashCode => super.hashCode ^ 'PackageRef'.hashCode;
}

/// A reference to a specific version of a package.
///
/// A package ID contains enough information to correctly get the package.
///
/// It's possible for multiple distinct package IDs to point to different
/// packages that have identical contents. For example, the same package may be
/// available from multiple sources. As far as Pub is concerned, those packages
/// are different.
///
/// Note that a package ID's [description] field has a different structure than
/// the [PackageRef.description] or [PackageRange.description] fields for some
/// sources. For example, the `git` source adds revision information to the
/// description to ensure that the same ID always points to the same source.
class PackageId extends PackageName {
  /// The package's version.
  final Version version;

  /// Creates an ID for a package with the given [name], [source], [version],
  /// and [description].
  ///
  /// Since an ID's description is an implementation detail of its source, this
  /// should generally not be called outside of [Source] subclasses.
  PackageId(String name, Source? source, this.version, description)
      : super._(name, source, description);

  /// Creates an ID for the given root package.
  PackageId.root(Package package)
      : version = package.version,
        super._(package.name, null, package.name);

  @override
  int get hashCode => super.hashCode ^ version.hashCode;

  @override
  bool operator ==(other) =>
      other is PackageId && samePackage(other) && other.version == version;

  /// Returns a [PackageRange] that allows only [version] of this package.
  PackageRange toRange() => withConstraint(version);

  @override
  String toString([PackageDetail? detail]) {
    detail ??= PackageDetail.defaults;

    var buffer = StringBuffer(name);
    if (detail.showVersion ?? !isRoot) buffer.write(' $version');

    if (!isRoot && (detail.showSource ?? source is! HostedSource)) {
      buffer.write(' from $source');
      if (detail.showDescription) {
        buffer.write(' ${source!.formatDescription(description)}');
      }
    }

    return buffer.toString();
  }
}

/// A reference to a constrained range of versions of one package.
class PackageRange extends PackageName {
  /// The allowed package versions.
  final VersionConstraint constraint;

  /// The dependencies declared on features of the target package.
  final Map<String, FeatureDependency> features;

  /// Creates a reference to package with the given [name], [source],
  /// [constraint], and [description].
  ///
  /// Since an ID's description is an implementation detail of its source, this
  /// should generally not be called outside of [Source] subclasses.
  PackageRange(String name, Source? source, this.constraint, description,
      {Map<String, FeatureDependency>? features})
      : features = features == null
            ? const {}
            : UnmodifiableMapView(Map.from(features)),
        super._(name, source, description);

  /// Creates a range that selects the root package.
  PackageRange.root(Package package)
      : constraint = package.version,
        features = const {},
        super._(package.name, null, package.name);

  /// Returns a description of [features], or the empty string if [features] is
  /// empty.
  String get featureDescription {
    if (features.isEmpty) return '';

    var enabledFeatures = <String>[];
    var disabledFeatures = <String>[];
    features.forEach((name, type) {
      if (type == FeatureDependency.unused) {
        disabledFeatures.add(name);
      } else {
        enabledFeatures.add(name);
      }
    });

    var description = '';
    if (enabledFeatures.isNotEmpty) {
      description += 'with ${toSentence(enabledFeatures)}';
      if (disabledFeatures.isNotEmpty) description += ', ';
    }

    if (disabledFeatures.isNotEmpty) {
      description += 'without ${toSentence(disabledFeatures)}';
    }
    return description;
  }

  @override
  String toString([PackageDetail? detail]) {
    detail ??= PackageDetail.defaults;

    var buffer = StringBuffer(name);
    if (detail.showVersion ?? _showVersionConstraint) {
      buffer.write(' $constraint');
    }

    if (!isRoot && (detail.showSource ?? source is! HostedSource)) {
      buffer.write(' from $source');
      if (detail.showDescription) {
        buffer.write(' ${source!.formatDescription(description)}');
      }
    }

    if (detail.showFeatures && features.isNotEmpty) {
      buffer.write(' $featureDescription');
    }

    return buffer.toString();
  }

  /// Whether to include the version constraint in [toString] by default.
  bool get _showVersionConstraint {
    if (isRoot) return false;
    if (!constraint.isAny) return true;
    return source!.hasMultipleVersions;
  }

  /// Returns a new [PackageRange] with [features] merged with [this.features].
  PackageRange withFeatures(Map<String, FeatureDependency> features) {
    if (features.isEmpty) return this;
    return PackageRange(name, source, constraint, description,
        features: Map.from(this.features)..addAll(features));
  }

  /// Returns a copy of [this] with the same semantics, but with a `^`-style
  /// constraint if possible.
  PackageRange withTerseConstraint() {
    if (constraint is! VersionRange) return this;
    if (constraint.toString().startsWith('^')) return this;

    var range = constraint as VersionRange;
    if (!range.includeMin) return this;
    if (range.includeMax) return this;
    var min = range.min;
    if (min == null) return this;
    if (range.max == min.nextBreaking.firstPreRelease) {
      return withConstraint(VersionConstraint.compatibleWith(min));
    } else {
      return this;
    }
  }

  /// Whether [id] satisfies this dependency.
  ///
  /// Specifically, whether [id] refers to the same package as [this] *and*
  /// [constraint] allows `id.version`.
  bool allows(PackageId id) => samePackage(id) && constraint.allows(id.version);

  @override
  int get hashCode =>
      super.hashCode ^ constraint.hashCode ^ _featureEquality.hash(features);

  @override
  bool operator ==(other) =>
      other is PackageRange &&
      samePackage(other) &&
      other.constraint == constraint &&
      _featureEquality.equals(other.features, features);
}

/// An enum of types of dependencies on a [Feature].
class FeatureDependency {
  /// The feature must exist and be enabled for this dependency to be satisfied.
  static const required = FeatureDependency._('required');

  /// The feature must be enabled if it exists, but is not required to exist for
  /// this dependency to be satisfied.
  static const ifAvailable = FeatureDependency._('if available');

  /// The feature is neither required to exist nor to be enabled for this
  /// feature to be satisfied.
  static const unused = FeatureDependency._('unused');

  final String _name;

  /// Whether this type of dependency enables the feature it depends on.
  bool get isEnabled => this != unused;

  const FeatureDependency._(this._name);

  @override
  String toString() => _name;
}

/// An enum of different levels of detail that can be used when displaying a
/// terse package name.
class PackageDetail {
  /// The default [PackageDetail] configuration.
  static const defaults = PackageDetail();

  /// Whether to show the package version or version range.
  ///
  /// If this is `null`, the version is shown for all packages other than root
  /// [PackageId]s or [PackageRange]s with `git` or `path` sources and `any`
  /// constraints.
  final bool? showVersion;

  /// Whether to show the package source.
  ///
  /// If this is `null`, the source is shown for all non-hosted, non-root
  /// packages. It's always `true` if [showDescription] is `true`.
  final bool? showSource;

  /// Whether to show the package description.
  ///
  /// This defaults to `false`.
  final bool showDescription;

  /// Whether to show the package features.
  ///
  /// This defaults to `true`.
  final bool showFeatures;

  const PackageDetail(
      {this.showVersion,
      bool? showSource,
      bool? showDescription,
      bool? showFeatures})
      : showSource = showDescription == true ? true : showSource,
        showDescription = showDescription ?? false,
        showFeatures = showFeatures ?? true;

  /// Returns a [PackageDetail] with the maximum amount of detail between [this]
  /// and [other].
  PackageDetail max(PackageDetail other) => PackageDetail(
      showVersion: showVersion! || other.showVersion!,
      showSource: showSource! || other.showSource!,
      showDescription: showDescription || other.showDescription,
      showFeatures: showFeatures || other.showFeatures);
}
