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

import 'dart:io' as io;

import 'file_system.dart';

import '../fasta/compiler_context.dart' show CompilerContext;

/// Concrete implementation of [FileSystem] handling standard URI schemes.
///
/// file: URIs are handled using file I/O.
/// data: URIs return their data contents.
///
/// Not intended to be implemented or extended by clients.
class StandardFileSystem implements FileSystem {
  static final StandardFileSystem instance = new StandardFileSystem._();

  StandardFileSystem._();

  @override
  FileSystemEntity entityForUri(Uri uri) {
    if (uri.isScheme('file')) {
      return new _IoFileSystemEntity(uri);
    } else if (!uri.hasScheme) {
      // TODO(askesc): Empty schemes should have been handled elsewhere.
      return new _IoFileSystemEntity(Uri.base.resolveUri(uri));
    } else if (uri.isScheme('data')) {
      return new DataFileSystemEntity(Uri.base.resolveUri(uri));
    } else {
      throw new FileSystemException(
          uri, 'StandardFileSystem only supports file:* and data:* URIs');
    }
  }
}

/// Concrete implementation of [FileSystemEntity] for file: URIs.
class _IoFileSystemEntity implements FileSystemEntity {
  @override
  final Uri uri;

  _IoFileSystemEntity(this.uri);

  @override
  int get hashCode => uri.hashCode;

  @override
  bool operator ==(Object other) =>
      other is _IoFileSystemEntity && other.uri == uri;

  @override
  Future<bool> exists() {
    if (new io.File.fromUri(uri).existsSync()) {
      return new Future.value(true);
    }
    if (io.FileSystemEntity.isDirectorySync(uri.toFilePath())) {
      return new Future.value(true);
    }
    // TODO(CFE-team): What about [Link]s?
    return new Future.value(false);
  }

  @override
  Future<bool> existsAsyncIfPossible() async {
    if (await new io.File.fromUri(uri).exists()) {
      return true;
    }
    if (await io.FileSystemEntity.isDirectory(uri.toFilePath())) {
      return true;
    }
    // TODO(CFE-team): What about [Link]s?
    return false;
  }

  @override
  Future<List<int>> readAsBytes() {
    try {
      CompilerContext.recordDependency(uri);
      return new Future.value(new io.File.fromUri(uri).readAsBytesSync());
    } on io.FileSystemException catch (exception) {
      return new Future.error(
          _toFileSystemException(exception), StackTrace.current);
    }
  }

  @override
  Future<List<int>> readAsBytesAsyncIfPossible() async {
    try {
      CompilerContext.recordDependency(uri);
      return await new io.File.fromUri(uri).readAsBytes();
    } on io.FileSystemException catch (exception) {
      throw _toFileSystemException(exception);
    }
  }

  @override
  Future<String> readAsString() async {
    try {
      CompilerContext.recordDependency(uri);
      return await new io.File.fromUri(uri).readAsString();
    } on io.FileSystemException catch (exception) {
      throw _toFileSystemException(exception);
    }
  }

  /**
   * Return the [FileSystemException] for the given I/O exception.
   */
  FileSystemException _toFileSystemException(io.FileSystemException exception) {
    String message = exception.message;
    String? osMessage = exception.osError?.message;
    if (osMessage != null && osMessage.isNotEmpty) {
      message = osMessage;
    }
    return new FileSystemException(uri, message);
  }
}

/// Concrete implementation of [FileSystemEntity] for data: URIs.
class DataFileSystemEntity implements FileSystemEntity {
  @override
  final Uri uri;

  DataFileSystemEntity(this.uri)
      : assert(uri.isScheme('data')),
        assert(uri.data != null);

  @override
  int get hashCode => uri.hashCode;

  @override
  bool operator ==(Object other) =>
      other is DataFileSystemEntity && other.uri == uri;

  @override
  Future<bool> exists() {
    return new Future.value(true);
  }

  @override
  Future<List<int>> readAsBytes() {
    return new Future.value(uri.data!.contentAsBytes());
  }

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

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

  @override
  Future<String> readAsString() {
    return new Future.value(uri.data!.contentAsString());
  }
}
