// 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 front_end.memory_file_system;

import 'dart:convert';
import 'dart:typed_data';

import 'file_system.dart';

/// Concrete implementation of [FileSystem] which performs its operations on an
/// in-memory virtual file system.
///
/// Not intended to be implemented or extended by clients.
class MemoryFileSystem implements FileSystem {
  final Map<Uri, Uint8List> _files = {};
  final Set<Uri> _directories = new Set<Uri>();

  /// The "current directory" in the in-memory virtual file system.
  ///
  /// This is used to convert relative URIs to absolute URIs.
  ///
  /// Always ends in a trailing '/'.
  Uri currentDirectory;

  MemoryFileSystem(Uri currentDirectory)
      : currentDirectory = _addTrailingSlash(currentDirectory) {
    _directories.add(currentDirectory);
  }

  @override
  MemoryFileSystemEntity entityForUri(Uri uri) {
    return new MemoryFileSystemEntity._(
        this, currentDirectory.resolveUri(uri).normalizePath());
  }

  String get debugString {
    StringBuffer sb = new StringBuffer();
    _files.forEach((uri, _) => sb.write("- $uri\n"));
    _directories.forEach((uri) => sb.write("- $uri\n"));
    return '$sb';
  }

  static Uri _addTrailingSlash(Uri uri) {
    if (!uri.path.endsWith('/')) {
      uri = uri.replace(path: uri.path + '/');
    }
    return uri;
  }
}

/// Concrete implementation of [FileSystemEntity] for use by
/// [MemoryFileSystem].
class MemoryFileSystemEntity implements FileSystemEntity {
  final MemoryFileSystem _fileSystem;

  @override
  final Uri uri;

  MemoryFileSystemEntity._(this._fileSystem, this.uri);

  @override
  int get hashCode => uri.hashCode;

  @override
  bool operator ==(Object other) =>
      other is MemoryFileSystemEntity &&
      other.uri == uri &&
      identical(other._fileSystem, _fileSystem);

  /// Create a directory for this file system entry.
  ///
  /// If the entry is an existing file, this is an error.
  void createDirectory() {
    if (_fileSystem._files[uri] != null) {
      throw new FileSystemException(uri, 'Entry $uri is a file.');
    }
    _fileSystem._directories.add(uri);
  }

  @override
  Future<bool> exists() async {
    return _fileSystem._files[uri] != null ||
        _fileSystem._directories.contains(uri);
  }

  @override
  Future<bool> existsAsyncIfPossible() => exists();

  @override
  Future<List<int>> readAsBytes() async {
    Uint8List? contents = _fileSystem._files[uri];
    if (contents == null) {
      throw new FileSystemException(uri, 'File $uri does not exist.');
    }
    return contents;
  }

  @override
  Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();

  @override
  Future<String> readAsString() async {
    List<int> bytes = await readAsBytes();
    try {
      return utf8.decode(bytes);
    } on FormatException catch (e) {
      throw new FileSystemException(uri, e.message);
    }
  }

  /// Writes the given raw bytes to this file system entity.
  ///
  /// If no file exists, one is created.  If a file exists already, it is
  /// overwritten.
  void writeAsBytesSync(List<int> bytes) {
    if (bytes is Uint8List) {
      _update(uri, bytes);
    } else {
      _update(uri, new Uint8List.fromList(bytes));
    }
  }

  /// Writes the given string to this file system entity.
  ///
  /// The string is encoded as UTF-8.
  ///
  /// If no file exists, one is created.  If a file exists already, it is
  /// overwritten.
  void writeAsStringSync(String s) {
    // Note: the return type of utf8.encode is List<int>, but in practice it
    // always returns Uint8List.  We rely on that for efficiency, so that we
    // don't have to make an extra copy.
    _update(uri, utf8.encode(s) as Uint8List);
  }

  void _update(Uri uri, Uint8List data) {
    if (_fileSystem._directories.contains(uri)) {
      throw new FileSystemException(uri, 'Entry $uri is a directory.');
    }
    _fileSystem._files[uri] = data;
  }
}
