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

library analyzer.src.source.source_resource;

import 'dart:collection';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';

/**
 * A function that can translate the contents of files on disk as they are read.
 * This is now obsolete, but supported the ability of server to deal with
 * clients that convert all text to an internal format.
 */
typedef String FileReadMode(String s);

/**
 * A source that represents a file.
 */
class FileSource extends Source {
  /**
   * A function that changes the way that files are read off of disk.
   */
  static FileReadMode fileReadMode = (String s) => s;

  /**
   * Map from encoded URI/filepath pair to a unique integer identifier.  This
   * identifier is used for equality tests and hash codes.
   *
   * The URI and filepath are joined into a pair by separating them with an '@'
   * character.
   */
  static final Map<String, int> _idTable = new HashMap<String, int>();

  /**
   * The URI from which this source was originally derived.
   */
  @override
  final Uri uri;

  /**
   * The unique ID associated with this source.
   */
  final int id;

  /**
   * The file represented by this source.
   */
  final File file;

  /**
   * The cached absolute path of this source.
   */
  String _absolutePath;

  /**
   * The cached encoding for this source.
   */
  String _encoding;

  /**
   * Initialize a newly created source object to represent the given [file]. If
   * a [uri] is given, then it will be used as the URI from which the source was
   * derived, otherwise a `file:` URI will be created based on the [file].
   */
  FileSource(File file, [Uri uri])
      : this.uri = uri ?? file.toUri(),
        this.file = file,
        id = _idTable.putIfAbsent(
            '${uri ?? file.toUri()}@${file.path}', () => _idTable.length);

  @override
  TimestampedData<String> get contents {
    return PerformanceStatistics.io.makeCurrentWhile(() {
      return contentsFromFile;
    });
  }

  /**
   * Get and return the contents and timestamp of the underlying file.
   *
   * 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.
   *
   * Throws an exception if the contents of this source could not be accessed.
   * See [contents].
   */
  TimestampedData<String> get contentsFromFile {
    return new TimestampedData<String>(
        modificationStamp, fileReadMode(file.readAsStringSync()));
  }

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

  @override
  String get fullName => _absolutePath ??= file.path;

  @override
  int get hashCode => uri.hashCode;

  @override
  bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;

  @override
  int get modificationStamp {
    try {
      return file.modificationStamp;
    } on FileSystemException {
      return -1;
    }
  }

  @override
  String get shortName => file.shortName;

  @override
  UriKind get uriKind => UriKind.fromScheme(uri.scheme);

  @override
  bool operator ==(Object object) {
    if (object is FileSource) {
      return id == object.id;
    } else if (object is Source) {
      return uri == object.uri;
    }
    return false;
  }

  @override
  bool exists() => file.exists;

  @override
  String toString() {
    if (file == null) {
      return "<unknown source>";
    }
    return file.path;
  }
}
