// 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:built_value/built_value.dart';
import 'package:meta/meta.dart';

import '../base.dart';
import '../visitors.dart';
import 'expression.dart';
import 'type_reference.dart';

/// Short-hand for `Reference(symbol, url)`.
Reference refer(String symbol, [String? url]) => Reference(symbol, url);

/// A reference to [symbol], such as a class, or top-level method or field.
///
/// References can be collected and collated in order to automatically generate
/// `import` statements for all used symbols.
@immutable
class Reference extends Expression implements Spec {
  /// Relative, `package:` or `dart:` URL of the library.
  ///
  /// May be omitted (`null`) in order to express "same library".
  final String? url;

  /// Name of the class, method, or field.
  ///
  /// May be `null` for references without symbols, for instance a function type
  /// has no symbol.
  final String? symbol;

  /// Create a reference to [symbol] in [url].
  const Reference(this.symbol, [this.url]);

  @override
  R accept<R>(SpecVisitor<R> visitor, [R? context]) =>
      visitor.visitReference(this, context);

  @override
  int get hashCode => '$url#$symbol'.hashCode;

  @override
  bool operator ==(Object other) =>
      other is Reference && other.url == url && other.symbol == symbol;

  /// Returns a new instance of this expression.
  Expression newInstance(
    Iterable<Expression> positionalArguments, [
    Map<String, Expression> namedArguments = const {},
    List<Reference> typeArguments = const [],
  ]) => InvokeExpression.newOf(
    this,
    positionalArguments.toList(),
    namedArguments,
    typeArguments,
  );

  /// Returns a new instance of this expression with a named constructor.
  Expression newInstanceNamed(
    String name,
    Iterable<Expression> positionalArguments, [
    Map<String, Expression> namedArguments = const {},
    List<Reference> typeArguments = const [],
  ]) => InvokeExpression.newOf(
    this,
    positionalArguments.toList(),
    namedArguments,
    typeArguments,
    name,
  );

  /// Returns a const instance of this expression.
  Expression constInstance(
    Iterable<Expression> positionalArguments, [
    Map<String, Expression> namedArguments = const {},
    List<Reference> typeArguments = const [],
  ]) => InvokeExpression.constOf(
    this,
    positionalArguments.toList(),
    namedArguments,
    typeArguments,
  );

  /// Returns a const instance of this expression with a named constructor.
  Expression constInstanceNamed(
    String name,
    Iterable<Expression> positionalArguments, [
    Map<String, Expression> namedArguments = const {},
    List<Reference> typeArguments = const [],
  ]) => InvokeExpression.constOf(
    this,
    positionalArguments.toList(),
    namedArguments,
    typeArguments,
    name,
  );

  @override
  String toString() =>
      (newBuiltValueToStringHelper('Reference')
            ..add('url', url)
            ..add('symbol', symbol))
          .toString();

  /// Returns as a [TypeReference], which allows adding generic type parameters.
  Reference get type => TypeReference(
    (b) =>
        b
          ..url = url
          ..symbol = symbol,
  );
}
