// Copyright (c) 2016, 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:path/path.dart' as pathos;

import 'analysis_target.dart';
import 'timestamped_data.dart';
import 'uri_kind.dart';

/// Base class providing implementations for the methods in [Source] that don't
/// require filesystem access.
abstract class BasicSource extends Source {
  final Uri uri;

  BasicSource(this.uri);

  @override
  String get encoding => uri.toString();

  @override
  String get fullName => encoding;

  @override
  int get hashCode => uri.hashCode;

  @override
  bool get isInSystemLibrary => uri.scheme == 'dart';

  @override
  String get shortName => pathos.basename(fullName);

  @override
  bool operator ==(Object object) => object is Source && object.uri == uri;
}

/**
 * The interface `Source` defines the behavior of objects representing source
 * code that can be analyzed by the analysis engine.
 *
 * Implementations of this interface need to be aware of some assumptions made
 * by the analysis engine concerning sources:
 *
 * * Sources are not required to be unique. That is, there can be multiple
 * instances representing the same source.
 * * Sources are long lived. That is, the engine is allowed to hold on to a
 * source for an extended period of time and that source must continue to
 * report accurate and up-to-date information.
 *
 * Because of these assumptions, most implementations will not maintain any
 * state but will delegate to an authoritative system of record in order to
 * implement this API. For example, a source that represents files on disk
 * would typically query the file system to determine the state of the file.
 *
 * If the instances that implement this API are the system of record, then they
 * will typically be unique. In that case, sources that are created that
 * represent non-existent files must also be retained so that if those files
 * are created at a later date the long-lived sources representing those files
 * will know that they now exist.
 */
abstract class Source implements AnalysisTarget {
  /**
   * An empty list of sources.
   */
  static const List<Source> EMPTY_LIST = const <Source>[];

  /**
   * Get the contents and timestamp of this source.
   *
   * Clients should consider using the method [AnalysisContext.getContents]
   * because contexts can have local overrides of the content of a source that
   * the source is not aware of.
   *
   * @return the contents and timestamp of the source
   * @throws Exception if the contents of this source could not be accessed
   */
  TimestampedData<String> get contents;

  /**
   * Return an encoded representation of this source that can be used to create
   * a source that is equal to this source.
   *
   * @return an encoded representation of this source
   * See [SourceFactory.fromEncoding].
   */
  String get encoding;

  /**
   * Return the full (long) version of the name that can be displayed to the
   * user to denote this source. For example, for a source representing a file
   * this would typically be the absolute path of the file.
   *
   * @return a name that can be displayed to the user to denote this source
   */
  String get fullName;

  /**
   * Return a hash code for this source.
   *
   * @return a hash code for this source
   * See [Object.hashCode].
   */
  @override
  int get hashCode;

  /**
   * Return `true` if this source is in one of the system libraries.
   *
   * @return `true` if this is in a system library
   */
  bool get isInSystemLibrary;

  @override
  Source get librarySource => null;

  /**
   * Return the modification stamp for this source, or a negative value if the
   * source does not exist. A modification stamp is a non-negative integer with
   * the property that if the contents of the source have not been modified
   * since the last time the modification stamp was accessed then the same
   * value will be returned, but if the contents of the source have been
   * modified one or more times (even if the net change is zero) the stamps
   * will be different.
   *
   * Clients should consider using the method
   * [AnalysisContext.getModificationStamp] because contexts can have local
   * overrides of the content of a source that the source is not aware of.
   */
  int get modificationStamp;

  /**
   * Return a short version of the name that can be displayed to the user to
   * denote this source. For example, for a source representing a file this
   * would typically be the name of the file.
   *
   * @return a name that can be displayed to the user to denote this source
   */
  String get shortName;

  @override
  Source get source => this;

  /**
   * Return the URI from which this source was originally derived.
   *
   * @return the URI from which this source was originally derived
   */
  Uri get uri;

  /**
   * Return the kind of URI from which this source was originally derived. If
   * this source was created from an absolute URI, then the returned kind will
   * reflect the scheme of the absolute URI. If it was created from a relative
   * URI, then the returned kind will be the same as the kind of the source
   * against which the relative URI was resolved.
   *
   * @return the kind of URI from which this source was originally derived
   */
  UriKind get uriKind;

  /**
   * Return `true` if the given object is a source that represents the same
   * source code as this source.
   *
   * @param object the object to be compared with this object
   * @return `true` if the given object is a source that represents the same
   *         source code as this source
   * See [Object.==].
   */
  @override
  bool operator ==(Object object);

  /**
   * Return `true` if this source exists.
   *
   * Clients should consider using the method [AnalysisContext.exists] because
   * contexts can have local overrides of the content of a source that the
   * source is not aware of and a source with local content is considered to
   * exist even if there is no file on disk.
   *
   * @return `true` if this source exists
   */
  bool exists();
}
