// 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/git.dart';
import 'source/hosted.dart';
import 'source/path.dart';
import 'utils.dart';

/// The equality to use when comparing the feature sets of two package names.
final _featureEquality = const 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 description;

  /// Whether this is a name for a magic package.
  ///
  /// Magic packages are unversioned pub constructs that have special semantics.
  /// For example, a magic package named "pub itself" is inserted into the
  /// dependency graph when any package depends on barback. This packages has
  /// dependencies that represent the versions of barback and related packages
  /// that pub is compatible with.
  final bool isMagic;

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

  PackageName._(this.name, this.source, this.description) : isMagic = false;

  PackageName._magic(this.name)
      : source = null,
        description = null,
        isMagic = true;

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

  /// Returns a [PackageRange] for this package with the given version constraint.
  PackageRange withConstraint(VersionConstraint constraint) =>
      new 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;
    if (source == null) return other.source == null;

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

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

  /// Returns a string representation of this package name.
  ///
  /// If [detail] is passed, it controls exactly which details are included.
  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);

  /// Creates a reference to a magic package (see [isMagic]).
  PackageRef.magic(String name) : super._magic(name);

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

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

    return buffer.toString();
  }

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

/// 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 a magic package (see [isMagic]).
  PackageId.magic(String name)
      : version = Version.none,
        super._magic(name);

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

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

  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);

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

    var buffer = new 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 {}
            : new UnmodifiableMapView(new Map.from(features)),
        super._(name, source, description);

  PackageRange.magic(String name)
      : constraint = Version.none,
        features = const {},
        super._magic(name);

  /// 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;
  }

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

    var buffer = new 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;
    if (source is PathSource) return false;
    if (source is GitSource) return false;
    return true;
  }

  /// Returns a new [PackageRange] with [features] merged with [this.features].
  PackageRange withFeatures(Map<String, FeatureDependency> features) {
    if (features.isEmpty) return this;
    return new PackageRange(name, source, constraint, description,
        features: new 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 &&
        !range.includeMax &&
        range.min != null &&
        range.max == range.min.nextBreaking) {
      return withConstraint(new VersionConstraint.compatibleWith(range.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);

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

  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 = const 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 = const FeatureDependency._("if available");

  /// The feature is neither required to exist nor to be enabled for this
  /// feature to be satisfied.
  static const unused = const 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);

  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 = const 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) => new PackageDetail(
      showVersion: this.showVersion || other.showVersion,
      showSource: this.showSource || other.showSource,
      showDescription: this.showDescription || other.showDescription,
      showFeatures: this.showFeatures || other.showFeatures);
}
