// Copyright (c) 2013, 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.

// @dart = 2.10

library source_file_provider;

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:front_end/src/api_unstable/dart2js.dart' as fe;

import '../compiler_api.dart' as api;
import 'colors.dart' as colors;
import 'dart2js.dart' show AbortLeg;
import 'io/source_file.dart';

abstract class SourceFileProvider implements api.CompilerInput {
  bool isWindows = (Platform.operatingSystem == 'windows');
  Uri cwd = Uri.base;
  Map<Uri, api.Input> utf8SourceFiles = <Uri, api.Input>{};
  Map<Uri, api.Input> binarySourceFiles = <Uri, api.Input>{};
  int dartCharactersRead = 0;

  Future<api.Input<List<int>>> readBytesFromUri(
      Uri resourceUri, api.InputKind inputKind) {
    if (!resourceUri.isAbsolute) {
      resourceUri = cwd.resolveUri(resourceUri);
    }
    api.Input<List<int>> input = _loadInputFromCache(resourceUri, inputKind);
    if (input != null) return Future.value(input);

    if (resourceUri.isScheme('file')) {
      return _readFromFile(resourceUri, inputKind);
    } else if (resourceUri.isScheme('http') || resourceUri.isScheme('https')) {
      return _readFromHttp(resourceUri, inputKind);
    } else {
      throw ArgumentError("Unknown scheme in uri '$resourceUri'");
    }
  }

  /// Fetches any existing value of [resourceUri] in a cache.
  ///
  /// For `api.InputKind.UTF8` inputs, this looks up both the cache of
  /// utf8 source files and binary source files. This is done today because of
  /// how dart2js binds to the CFE's file system. While dart2js reads sources as
  /// utf8, the CFE file system may read them as binary inputs. In case the CFE
  /// needs to report errors, dart2js will only find the location data if it
  /// checks both caches.
  api.Input<List<int>> _loadInputFromCache(
      Uri resourceUri, api.InputKind inputKind) {
    switch (inputKind) {
      case api.InputKind.UTF8:
        var input = utf8SourceFiles[resourceUri];
        if (input != null) return input;
        input = binarySourceFiles[resourceUri];
        if (input == null) return null;
        return _storeSourceInCache(resourceUri, input.data, api.InputKind.UTF8);
      case api.InputKind.binary:
        return binarySourceFiles[resourceUri];
    }
    return null;
  }

  /// Adds [source] to the cache under the [resourceUri] key.
  api.Input _storeSourceInCache(
      Uri resourceUri, List<int> source, api.InputKind inputKind) {
    switch (inputKind) {
      case api.InputKind.UTF8:
        return utf8SourceFiles[resourceUri] = CachingUtf8BytesSourceFile(
            resourceUri, relativizeUri(resourceUri), source);
      case api.InputKind.binary:
        return binarySourceFiles[resourceUri] = Binary(resourceUri, source);
    }
    return null;
  }

  @override
  void registerUtf8ContentsForDiagnostics(Uri resourceUri, List<int> source) {
    if (!resourceUri.isAbsolute) {
      resourceUri = cwd.resolveUri(resourceUri);
    }
    if (!utf8SourceFiles.containsKey(resourceUri)) {
      _storeSourceInCache(resourceUri, source, api.InputKind.UTF8);
    }
  }

  api.Input _readFromFileSync(Uri resourceUri, api.InputKind inputKind) {
    assert(resourceUri.isScheme('file'));
    List<int> source;
    try {
      source = readAll(resourceUri.toFilePath(),
          zeroTerminated: inputKind == api.InputKind.UTF8);
    } on FileSystemException catch (ex) {
      String message = ex.osError?.message;
      String detail = message != null ? ' ($message)' : '';
      throw "Error reading '${relativizeUri(resourceUri)}' $detail";
    }
    dartCharactersRead += source.length;
    return _storeSourceInCache(resourceUri, source, inputKind);
  }

  /// Read [resourceUri] directly as a UTF-8 file. If reading fails, `null` is
  /// returned.
  api.Input readUtf8FromFileSyncForTesting(Uri resourceUri) {
    try {
      return _readFromFileSync(resourceUri, api.InputKind.UTF8);
    } catch (e) {
      // Silence the error. The [resourceUri] was not requested by the user and
      // was only needed to give better error messages.
      return null;
    }
  }

  Future<api.Input<List<int>>> _readFromFile(
      Uri resourceUri, api.InputKind inputKind) {
    api.Input<List<int>> input;
    try {
      input = _readFromFileSync(resourceUri, inputKind);
    } catch (e) {
      return Future.error(e);
    }
    return Future.value(input);
  }

  Future<api.Input<List<int>>> _readFromHttp(
      Uri resourceUri, api.InputKind inputKind) {
    assert(resourceUri.isScheme('http'));
    HttpClient client = HttpClient();
    return client
        .getUrl(resourceUri)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
      if (response.statusCode != HttpStatus.ok) {
        String msg = 'Failure getting $resourceUri: '
            '${response.statusCode} ${response.reasonPhrase}';
        throw msg;
      }
      return response.toList();
    }).then((List<List<int>> splitContent) {
      int totalLength = splitContent.fold(0, (int old, List list) {
        return old + list.length;
      });
      Uint8List result = Uint8List(totalLength);
      int offset = 0;
      for (List<int> contentPart in splitContent) {
        result.setRange(offset, offset + contentPart.length, contentPart);
        offset += contentPart.length;
      }
      dartCharactersRead += totalLength;
      api.Input<List<int>> input;
      switch (inputKind) {
        case api.InputKind.UTF8:
          input = utf8SourceFiles[resourceUri] = CachingUtf8BytesSourceFile(
              resourceUri, resourceUri.toString(), result);
          break;
        case api.InputKind.binary:
          input = binarySourceFiles[resourceUri] = Binary(resourceUri, result);
          break;
      }
      return input;
    });
  }

  relativizeUri(Uri uri) => fe.relativizeUri(cwd, uri, isWindows);

  SourceFile<List<int>> getUtf8SourceFile(Uri resourceUri) {
    return _loadInputFromCache(resourceUri, api.InputKind.UTF8);
  }

  Iterable<Uri> getSourceUris() {
    Set<Uri> uris = Set<Uri>();
    // Note: this includes also indirect sources that were used to create
    // `.dill` inputs to the compiler. This is OK, since this API is only
    // used to calculate DEPS for gn build systems.
    uris.addAll(utf8SourceFiles.keys);
    uris.addAll(binarySourceFiles.keys);
    return uris;
  }
}

List<int> readAll(String filename, {bool zeroTerminated = true}) {
  RandomAccessFile file = File(filename).openSync();
  int length = file.lengthSync();
  int bufferLength = length;
  if (zeroTerminated) {
    // +1 to have a 0 terminated list, see [Scanner].
    bufferLength++;
  }
  var buffer = Uint8List(bufferLength);
  file.readIntoSync(buffer, 0, length);
  file.closeSync();
  return buffer;
}

class CompilerSourceFileProvider extends SourceFileProvider {
  @override
  Future<api.Input<List<int>>> readFromUri(Uri uri,
          {api.InputKind inputKind = api.InputKind.UTF8}) =>
      readBytesFromUri(uri, inputKind);
}

class FormattingDiagnosticHandler implements api.CompilerDiagnostics {
  final SourceFileProvider provider;
  bool showWarnings = true;
  bool showHints = true;
  bool verbose = false;
  bool isAborting = false;
  bool enableColors = false;
  bool throwOnError = false;
  int throwOnErrorCount = 0;
  api.Diagnostic lastKind = null;
  int fatalCount = 0;

  final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal;
  final int INFO =
      api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal;

  FormattingDiagnosticHandler([SourceFileProvider provider])
      : this.provider =
            (provider == null) ? CompilerSourceFileProvider() : provider;

  void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
    if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
    if (enableColors) {
      print('${colors.green("Info:")} $message');
    } else {
      print('Info: $message');
    }
  }

  /// Adds [kind] specific prefix to [message].
  String prefixMessage(String message, api.Diagnostic kind) {
    switch (kind) {
      case api.Diagnostic.ERROR:
        return 'Error: $message';
      case api.Diagnostic.WARNING:
        return 'Warning: $message';
      case api.Diagnostic.HINT:
        return 'Hint: $message';
      case api.Diagnostic.CRASH:
        return 'Internal Error: $message';
      case api.Diagnostic.INFO:
      case api.Diagnostic.VERBOSE_INFO:
        return 'Info: $message';
    }
    throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})';
  }

  @override
  void report(var code, Uri uri, int begin, int end, String message,
      api.Diagnostic kind) {
    if (isAborting) return;
    isAborting = (kind == api.Diagnostic.CRASH);

    bool fatal = (kind.ordinal & FATAL) != 0;
    bool isInfo = (kind.ordinal & INFO) != 0;
    if (isInfo && uri == null && kind != api.Diagnostic.INFO) {
      info(message, kind);
      return;
    }

    message = prefixMessage(message, kind);

    // [lastKind] records the previous non-INFO kind we saw.
    // This is used to suppress info about a warning when warnings are
    // suppressed, and similar for hints.
    if (kind != api.Diagnostic.INFO) {
      lastKind = kind;
    }
    String Function(String) color;
    if (kind == api.Diagnostic.ERROR) {
      color = colors.red;
    } else if (kind == api.Diagnostic.WARNING) {
      if (!showWarnings) return;
      color = colors.magenta;
    } else if (kind == api.Diagnostic.HINT) {
      if (!showHints) return;
      color = colors.cyan;
    } else if (kind == api.Diagnostic.CRASH) {
      color = colors.red;
    } else if (kind == api.Diagnostic.INFO) {
      if (lastKind == api.Diagnostic.WARNING && !showWarnings) return;
      if (lastKind == api.Diagnostic.HINT && !showHints) return;
      color = colors.green;
    } else {
      throw 'Unknown kind: $kind (${kind.ordinal})';
    }
    if (!enableColors) {
      color = (String x) => x;
    }
    if (uri == null) {
      print('${color(message)}');
    } else {
      api.Input file = provider.getUtf8SourceFile(uri);
      if (file is SourceFile) {
        print(file.getLocationMessage(color(message), begin, end,
            colorize: color));
      } else {
        String position = end - begin > 0 ? '@$begin+${end - begin}' : '';
        print('${provider.relativizeUri(uri)}$position:\n'
            '${color(message)}');
      }
    }
    if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) {
      isAborting = true;
      throw AbortLeg(message);
    }
  }
}

typedef MessageCallback = void Function(String message);

class RandomAccessFileOutputProvider implements api.CompilerOutput {
  final Uri out;
  final Uri sourceMapOut;
  final MessageCallback onInfo;
  final MessageCallback onFailure;

  int totalCharactersWritten = 0;
  int totalCharactersWrittenPrimary = 0;
  int totalCharactersWrittenJavaScript = 0;
  int totalDataWritten = 0;

  List<String> allOutputFiles = <String>[];

  RandomAccessFileOutputProvider(this.out, this.sourceMapOut,
      {this.onInfo, this.onFailure});

  Uri createUri(String name, String extension, api.OutputType type) {
    Uri uri;
    // TODO(johnniwinther): Unify handle of [name] and [extension] to prepare
    // for using a single, possibly relative, [uri] as input.
    switch (type) {
      case api.OutputType.js:
        if (name == '') {
          uri = out;
        } else {
          uri = out.resolve('$name.$extension');
        }
        break;
      case api.OutputType.sourceMap:
        if (name == '') {
          uri = sourceMapOut;
        } else {
          uri = out.resolve('$name.$extension');
        }
        break;
      case api.OutputType.jsPart:
        uri = out.resolve('$name.$extension');
        break;
      case api.OutputType.dumpInfo:
      case api.OutputType.dumpUnusedLibraries:
      case api.OutputType.deferredMap:
        if (name == '') {
          name = out.pathSegments.last;
        }
        if (extension == '') {
          uri = out.resolve(name);
        } else {
          uri = out.resolve('$name.$extension');
        }
        break;
      case api.OutputType.debug:
        if (name == '') {
          name = out.pathSegments.last;
        }
        uri = out.resolve('$name.$extension');
        break;
      default:
        onFailure('Unknown output type: $type');
    }
    return uri;
  }

  @override
  api.OutputSink createOutputSink(
      String name, String extension, api.OutputType type) {
    Uri uri = createUri(name, extension, type);
    bool isPrimaryOutput = uri == out;

    if (!uri.isScheme('file')) {
      onFailure('Unhandled scheme ${uri.scheme} in $uri.');
    }

    RandomAccessFile output;
    try {
      output = (File(uri.toFilePath())..createSync(recursive: true))
          .openSync(mode: FileMode.write);
    } on FileSystemException catch (e) {
      onFailure('$e');
    }

    allOutputFiles.add(fe.relativizeUri(Uri.base, uri, Platform.isWindows));

    int charactersWritten = 0;

    void writeStringSync(String data) {
      // Write the data in chunks of 8kb, otherwise we risk running OOM.
      int chunkSize = 8 * 1024;

      int offset = 0;
      while (offset < data.length) {
        String chunk;
        int cut = offset + chunkSize;
        if (cut < data.length) {
          // Don't break the string in the middle of a code point encoded as two
          // surrogate pairs since `writeStringSync` will encode the unpaired
          // surrogates as U+FFFD REPLACEMENT CHARACTER.
          int lastCodeUnit = data.codeUnitAt(cut - 1);
          if (_isLeadSurrogate(lastCodeUnit)) {
            cut -= 1;
          }
          chunk = data.substring(offset, cut);
        } else {
          chunk = offset == 0 ? data : data.substring(offset);
        }
        output.writeStringSync(chunk);
        offset += chunk.length;
      }
      charactersWritten += data.length;
    }

    void onDone() {
      output.closeSync();
      totalCharactersWritten += charactersWritten;
      if (isPrimaryOutput) {
        totalCharactersWrittenPrimary += charactersWritten;
      }
      if (type == api.OutputType.js || type == api.OutputType.jsPart) {
        totalCharactersWrittenJavaScript += charactersWritten;
      }
    }

    return _OutputSinkWrapper(writeStringSync, onDone);
  }

  static bool _isLeadSurrogate(int codeUnit) => (codeUnit & 0xFC00) == 0xD800;

  @override
  api.BinaryOutputSink createBinarySink(Uri uri) {
    uri = Uri.base.resolveUri(uri);

    allOutputFiles.add(fe.relativizeUri(Uri.base, uri, Platform.isWindows));

    if (!uri.isScheme('file')) {
      onFailure('Unhandled scheme ${uri.scheme} in $uri.');
    }

    RandomAccessFile output;
    try {
      output = (File(uri.toFilePath())..createSync(recursive: true))
          .openSync(mode: FileMode.write);
    } on FileSystemException catch (e) {
      onFailure('$e');
    }

    int bytesWritten = 0;

    void writeBytesSync(List<int> data, [int start = 0, int end]) {
      output.writeFromSync(data, start, end);
      bytesWritten += (end ?? data.length) - start;
    }

    void onDone() {
      output.closeSync();
      totalDataWritten += bytesWritten;
    }

    return _BinaryOutputSinkWrapper(writeBytesSync, onDone);
  }
}

class RandomAccessBinaryOutputSink implements api.BinaryOutputSink {
  final RandomAccessFile output;

  RandomAccessBinaryOutputSink(Uri uri)
      : output = File.fromUri(uri).openSync(mode: FileMode.write);

  @override
  void write(List<int> buffer, [int start = 0, int end]) {
    output.writeFromSync(buffer, start, end);
  }

  @override
  void close() {
    output.closeSync();
  }
}

class _OutputSinkWrapper extends api.OutputSink {
  void Function(String) onAdd;
  void Function() onClose;

  _OutputSinkWrapper(this.onAdd, this.onClose);

  @override
  void add(String data) => onAdd(data);

  @override
  void close() => onClose();
}

class _BinaryOutputSinkWrapper extends api.BinaryOutputSink {
  void Function(List<int>, [int, int]) onWrite;
  void Function() onClose;

  _BinaryOutputSinkWrapper(this.onWrite, this.onClose);

  @override
  void write(List<int> data, [int start = 0, int end]) =>
      onWrite(data, start, end);

  @override
  void close() => onClose();
}

/// Adapter to integrate dart2js in bazel.
///
/// To handle bazel's special layout:
///
///  * We specify a .dart_tool/package_config.json configuration file that
///    expands packages to their corresponding bazel location.
///    This way there is no need to create a pub
///    cache prior to invoking dart2js.
///
///  * We provide an implicit mapping that can make all urls relative to the
///  bazel root.
///    To the compiler, URIs look like:
///      file:///bazel-root/a/b/c.dart
///
///    even though in the file system the file is located at:
///      file:///path/to/the/actual/bazel/root/a/b/c.dart
///
///    This mapping serves two purposes:
///      - It makes compiler results independent of the machine layout, which
///        enables us to share results across bazel runs and across machines.
///
///      - It hides the distinction between generated and source files. That way
///      we can use the standard package-resolution mechanism and ignore the
///      internals of how files are organized within bazel.
///
/// When invoking the compiler, bazel will use `package:` and
/// `file:///bazel-root/` URIs to specify entrypoints.
///
/// The mapping is specified using search paths relative to the current
/// directory. When this provider looks up a file, the bazel-root folder is
/// replaced by the first directory in the search path containing the file, if
/// any. For example, given the search path ".,bazel-bin/", and a URL
/// of the form `file:///bazel-root/a/b.dart`, this provider will check if the
/// file exists under "./a/b.dart", then check under "bazel-bin/a/b.dart".  If
/// none of the paths matches, it will attempt to load the file from
/// `/bazel-root/a/b.dart` which will likely fail.
class BazelInputProvider extends SourceFileProvider {
  final List<Uri> dirs;

  BazelInputProvider(List<String> searchPaths)
      : dirs = searchPaths.map(_resolve).toList();

  static Uri _resolve(String path) => Uri.base.resolve(path);

  @override
  Future<api.Input<List<int>>> readFromUri(Uri uri,
      {api.InputKind inputKind = api.InputKind.UTF8}) async {
    var resolvedUri = uri;
    var path = uri.path;
    if (path.startsWith('/bazel-root')) {
      path = path.substring('/bazel-root/'.length);
      for (var dir in dirs) {
        var file = dir.resolve(path);
        if (await File.fromUri(file).exists()) {
          resolvedUri = file;
          break;
        }
      }
    }
    api.Input<List<int>> result =
        await readBytesFromUri(resolvedUri, inputKind);
    if (uri != resolvedUri) {
      if (!resolvedUri.isAbsolute) {
        resolvedUri = cwd.resolveUri(resolvedUri);
      }
      switch (inputKind) {
        case api.InputKind.UTF8:
          utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
          break;
        case api.InputKind.binary:
          binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
          break;
      }
    }
    return result;
  }
}

/// Adapter to support one or more synthetic uri schemes.
///
/// These custom uris map to one or more real directories on the file system,
/// providing a merged view - or "overlay" file system.
///
/// This also allows for hermetic builds which do not encode machine specific
/// absolute uris by creating a synthetic "root" of the file system.
///
/// TODO(sigmund): Remove the [BazelInputProvider] in favor of this.
/// TODO(sigmund): Remove this and use the common `MultiRootFileSystem`
/// implementation.
class MultiRootInputProvider extends SourceFileProvider {
  final List<Uri> roots;
  final String markerScheme;

  MultiRootInputProvider(this.markerScheme, this.roots);

  @override
  Future<api.Input<List<int>>> readFromUri(Uri uri,
      {api.InputKind inputKind = api.InputKind.UTF8}) async {
    var resolvedUri = uri;
    if (resolvedUri.isScheme(markerScheme)) {
      var path = resolvedUri.path;
      if (path.startsWith('/')) path = path.substring(1);
      for (var dir in roots) {
        var fileUri = dir.resolve(path);
        if (await File.fromUri(fileUri).exists()) {
          resolvedUri = fileUri;
          break;
        }
      }
    }
    api.Input<List<int>> result =
        await readBytesFromUri(resolvedUri, inputKind);
    switch (inputKind) {
      case api.InputKind.UTF8:
        utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
        break;
      case api.InputKind.binary:
        binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
        break;
    }
    return result;
  }
}
