// 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.

library dart2js.elements.names;

import 'package:front_end/src/api_unstable/dart2js.dart' show $_;

import 'entities.dart' show LibraryEntity;

/// A [Name] represents the abstraction of a Dart identifier which takes privacy
/// and setter into account.
// TODO(johnniwinther): Try to share logic with [Selector].
abstract class Name {
  /// Create a [Name] for an identifier [text]. If [text] begins with '_' a
  /// private name with respect to [library] is created. If [isSetter] is `true`
  /// the created name represents the setter name 'text='.
  factory Name(String text, LibraryEntity? library, {bool isSetter = false}) {
    if (isPrivateName(text)) {
      return PrivateName(text, library!, isSetter: isSetter);
    }
    return PublicName(text, isSetter: isSetter);
  }

  /// The text of the name without prefixed library name or suffixed '=' if
  /// applicable.
  String get text;

  /// Is `true` if this name represents the name of a setter.
  bool get isSetter;

  /// Returns the getter name corresponding to this name. If this name is a
  /// setter name 'v=' then the name 'v' is returned, otherwise the name itself
  /// is returned.
  Name get getter;

  /// Returns the seeter name corresponding to this name. If this name is a
  /// getter name 'v' then the name 'v=' is returned, otherwsie the name itself
  /// is returned.
  Name get setter;

  /// Returns `true` if an entity of this name is accessible from library
  /// [element].
  bool isAccessibleFrom(LibraryEntity element);

  /// Returns `true` if this name is private.
  bool get isPrivate;

  /// Returns `true` if this name is the same as [other] not taking the library
  /// privacy into account.
  bool isSimilarTo(Name other);
  int get similarHashCode;

  // TODO(sra): Should this rather throw for public names?
  LibraryEntity? get library;

  /// Returns `true` when [s] is private if used as an identifier.
  static bool isPrivateName(String s) => !s.isEmpty && s.codeUnitAt(0) == $_;

  /// Returns `true` when [s] is public if used as an identifier.
  static bool isPublicName(String s) => !isPrivateName(s);
}

class PublicName implements Name {
  @override
  final String text;
  @override
  final bool isSetter;

  const PublicName(this.text, {this.isSetter = false});

  @override
  Name get getter => isSetter ? PublicName(text) : this;

  @override
  Name get setter => isSetter ? this : PublicName(text, isSetter: true);

  @override
  bool isAccessibleFrom(LibraryEntity element) => true;

  @override
  bool get isPrivate => false;

  @override
  int get hashCode => similarHashCode;

  @override
  bool operator ==(other) {
    if (other is! PublicName) return false;
    return isSimilarTo(other);
  }

  @override
  bool isSimilarTo(Name other) =>
      text == other.text && isSetter == other.isSetter;
  @override
  int get similarHashCode => text.hashCode + 11 * isSetter.hashCode;

  @override
  LibraryEntity? get library => null;

  @override
  String toString() => isSetter ? '$text=' : text;
}

class PrivateName extends PublicName {
  @override
  final LibraryEntity library;

  PrivateName(String text, this.library, {bool isSetter = false})
      : super(text, isSetter: isSetter);

  @override
  Name get getter => isSetter ? PrivateName(text, library) : this;

  @override
  Name get setter {
    return isSetter ? this : PrivateName(text, library, isSetter: true);
  }

  @override
  bool isAccessibleFrom(LibraryEntity element) => library == element;

  @override
  bool get isPrivate => true;

  @override
  int get hashCode => super.hashCode + 13 * library.hashCode;

  @override
  bool operator ==(other) {
    if (other is! PrivateName) return false;
    return super == (other) && library == other.library;
  }

  @override
  String toString() => '${library.name}#${super.toString()}';
}
