// Copyright (c) 2014, 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 'dart:async';
import 'dart:convert';

import 'package:pub_semver/pub_semver.dart';

import '../language_version.dart';
import '../package_name.dart';
import '../pubspec.dart';
import '../source.dart';
import '../system_cache.dart';

/// A [Null Object] that represents a source not recognized by pub.
///
/// It provides some default behavior so that pub can work with sources it
/// doesn't recognize.
///
/// [null object]: http://en.wikipedia.org/wiki/Null_Object_pattern
class UnknownSource extends Source {
  @override
  final String name;

  UnknownSource(this.name);

  /// Two unknown sources are the same if their names are the same.
  @override
  bool operator ==(Object other) =>
      other is UnknownSource && other.name == name;

  @override
  int get hashCode => name.hashCode;

  @override
  PackageRef parseRef(
    String name,
    Object? description, {
    required ResolvedDescription containingDescription,
    LanguageVersion? languageVersion,
  }) => PackageRef(name, UnknownDescription(description, this));

  @override
  PackageId parseId(
    String name,
    Version version,
    Object? description, {
    String? containingDir,
  }) => PackageId(
    name,
    version,
    ResolvedUnknownDescription(UnknownDescription(description, this)),
  );

  @override
  Future<List<PackageId>> doGetVersions(
    PackageRef ref,
    Duration? maxAge,
    SystemCache cache,
  ) =>
      throw UnsupportedError(
        "Cannot get package versions from unknown source '$name'.",
      );

  @override
  Future<Pubspec> doDescribe(PackageId id, SystemCache cache) =>
      throw UnsupportedError(
        "Cannot describe a package from unknown source '$name'.",
      );

  /// Returns the directory where this package can be found locally.
  @override
  String doGetDirectory(
    PackageId id,
    SystemCache cache, {
    String? relativeFrom,
  }) =>
      throw UnsupportedError(
        "Cannot find a package from an unknown source '$name'.",
      );
}

class UnknownDescription extends Description {
  final Object? description;
  @override
  final UnknownSource source;
  UnknownDescription(this.description, this.source);

  @override
  String format() {
    return json.encode(description);
  }

  @override
  Object? serializeForPubspec({
    required String? containingDir,
    required LanguageVersion languageVersion,
  }) {
    throw UnsupportedError(
      'Cannot serialize a package description '
      "from an unknown source '${source.name}'.",
    );
  }

  @override
  bool operator ==(Object other) =>
      other is UnknownDescription &&
      source.name == other.source.name &&
      json.encode(description) == json.encode(other.description);

  @override
  int get hashCode => Object.hash(source.name, json.encode(description));

  @override
  bool get hasMultipleVersions => false;
}

class ResolvedUnknownDescription extends ResolvedDescription {
  ResolvedUnknownDescription(UnknownDescription super.description);

  @override
  Object? serializeForLockfile({required String? containingDir}) {
    throw UnsupportedError(
      'Cannot serialize a package description '
      "from an unknown source '${description.source.name}'.",
    );
  }

  @override
  bool operator ==(Object other) =>
      other is ResolvedUnknownDescription && description == other.description;

  @override
  int get hashCode => description.hashCode;
}
