// 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:math' as math;
import 'dart:typed_data';

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

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

abstract class SourceFileProvider implements 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;
    switch (inputKind) {
      case api.InputKind.UTF8:
        input = utf8SourceFiles[resourceUri];
        break;
      case api.InputKind.binary:
        input = binarySourceFiles[resourceUri];
        break;
    }
    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'");
    }
  }

  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;
    api.Input input;
    switch (inputKind) {
      case api.InputKind.UTF8:
        input = utf8SourceFiles[resourceUri] = CachingUtf8BytesSourceFile(
            resourceUri, relativizeUri(resourceUri), source);
        break;
      case api.InputKind.binary:
        input = binarySourceFiles[resourceUri] = Binary(resourceUri, source);
        break;
    }
    return input;
  }

  /// Read [resourceUri] directly as a UTF-8 file. If reading fails, `null` is
  /// returned.
  api.Input autoReadFromFile(Uri resourceUri) {
    try {
      return _readFromFileSync(resourceUri, 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 utf8SourceFiles[resourceUri];
  }

  Iterable<Uri> getSourceUris() {
    Set<Uri> uris = Set<Uri>();
    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,
          {InputKind inputKind = InputKind.UTF8}) =>
      readBytesFromUri(uri, inputKind);
}

class FormattingDiagnosticHandler implements CompilerDiagnostics {
  final SourceFileProvider provider;
  bool showWarnings = true;
  bool showHints = true;
  bool verbose = false;
  bool isAborting = false;
  bool enableColors = false;
  bool throwOnError = false;
  bool autoReadFileUri = 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 == null &&
          autoReadFileUri &&
          (uri.isScheme('file') || !uri.isAbsolute) &&
          uri.path.endsWith('.dart')) {
        if (!uri.isAbsolute) {
          uri = provider.cwd.resolveUri(uri);
        }
        // When reading from .dill files, the original source files haven't been
        // loaded. Load the file if possible to provide a better error message.
        file = provider.autoReadFromFile(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 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, 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 OutputType.js:
        if (name == '') {
          uri = out;
        } else {
          uri = out.resolve('$name.$extension');
        }
        break;
      case OutputType.sourceMap:
        if (name == '') {
          uri = sourceMapOut;
        } else {
          uri = out.resolve('$name.$extension');
        }
        break;
      case OutputType.jsPart:
        uri = out.resolve('$name.$extension');
        break;
      case OutputType.dumpInfo:
      case OutputType.dumpUnusedLibraries:
      case OutputType.deferredMap:
        if (name == '') {
          name = out.pathSegments.last;
        }
        if (extension == '') {
          uri = out.resolve(name);
        } else {
          uri = out.resolve('$name.$extension');
        }
        break;
      case OutputType.debug:
        if (name == '') {
          name = out.pathSegments.last;
        }
        uri = out.resolve('$name.$extension');
        break;
      default:
        onFailure('Unknown output type: $type');
    }
    return uri;
  }

  @override
  OutputSink createOutputSink(String name, String extension, 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) {
        output.writeStringSync(
            data.substring(offset, math.min(offset + chunkSize, data.length)));
        offset += chunkSize;
      }
      charactersWritten += data.length;
    }

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

    return _OutputSinkWrapper(writeStringSync, onDone);
  }

  @override
  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 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 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 .packages 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,
      {InputKind inputKind = 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);
    switch (inputKind) {
      case InputKind.UTF8:
        utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
        break;
      case InputKind.binary:
        binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
        break;
    }
    return result;
  }

  @override
  api.Input autoReadFromFile(Uri resourceUri) {
    var path = resourceUri.path;
    if (path.startsWith('/bazel-root')) {
      path = path.substring('/bazel-root/'.length);
      for (var dir in dirs) {
        var file = dir.resolve(path);
        if (File.fromUri(file).existsSync()) {
          return super.autoReadFromFile(file);
        }
      }
    }
    return null;
  }
}

/// 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,
      {InputKind inputKind = 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 InputKind.UTF8:
        utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
        break;
      case InputKind.binary:
        binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
        break;
    }
    return result;
  }

  @override
  api.Input autoReadFromFile(Uri resourceUri) {
    if (resourceUri.isScheme(markerScheme)) {
      var path = resourceUri.path;
      for (var dir in roots) {
        var file = dir.resolve(path);
        if (File.fromUri(file).existsSync()) {
          return super.autoReadFromFile(file);
        }
      }
    }
    return null;
  }
}
