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

import 'dart:async' show Future;

import 'dart:convert' show UTF8;

import 'package:front_end/src/api_prototype/compiler_options.dart'
    show CompilerOptions;

import 'package:front_end/src/api_prototype/file_system.dart'
    show FileSystem, FileSystemEntity, FileSystemException;

import 'package:front_end/src/api_prototype/standard_file_system.dart'
    show StandardFileSystem;

import 'package:front_end/src/base/processed_options.dart'
    show ProcessedOptions;

import 'package:front_end/src/compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;

import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;

import 'package:front_end/src/kernel_generator_impl.dart'
    show CompilerResult, generateKernelInternal;

const String customScheme = "org-dartlang-bulkcompile";

final Uri mainUri = new Uri(scheme: customScheme, host: "", path: "/main.dart");

class BulkCompiler {
  final ProcessedOptions options;

  BulkCompiler(CompilerOptions options)
      : options = new ProcessedOptions(
            options
              ..packagesFileUri ??= Uri.base.resolve(".packages")
              ..linkedDependencies = <Uri>[
                computePlatformBinariesLocation().resolve("vm_platform.dill")
              ]
              ..fileSystem = (new FileBackedMemoryFileSystem()
                ..entities[mainUri.path] =
                    (new MemoryFileSystemEntity(mainUri)..bytes = <int>[])),
            false,
            <Uri>[mainUri]);

  Future<Null> compile(String source) {
    defineSource(mainUri.path, source);
    return CompilerContext.runWithOptions(options,
        (CompilerContext context) async {
      (await context.options.loadSdkSummary(null))?.computeCanonicalNames();
      CompilerResult result = await generateKernelInternal();
      result?.program?.unbindCanonicalNames();
      return null;
    });
  }

  void defineSource(String path, String source) {
    if (!path.startsWith("/")) {
      throw new ArgumentError("'path' should start with a slash ('/').");
    }
    Uri uri = new Uri(scheme: customScheme, host: "", path: path);
    MemoryFileSystemEntity entity = options.fileSystem.entityForUri(uri);
    entity.bytes = UTF8.encode(source);
  }
}

class FileBackedMemoryFileSystem implements FileSystem {
  final Map<String, MemoryFileSystemEntity> entities =
      <String, MemoryFileSystemEntity>{};

  FileSystemEntity entityForUri(Uri uri) {
    if (uri.scheme == customScheme) {
      MemoryFileSystemEntity entity = entities[uri.path];
      if (entity == null) {
        entity = new MemoryFileSystemEntity(uri);
        entities[uri.path] = entity;
      }
      return entity;
    } else {
      return StandardFileSystem.instance.entityForUri(uri);
    }
  }
}

class MemoryFileSystemEntity implements FileSystemEntity {
  final Uri uri;

  List<int> bytes;

  MemoryFileSystemEntity(this.uri);

  Future<List<int>> readAsBytes() {
    return bytes == null
        ? new Future.error(new FileSystemException(uri, "Not found"))
        : new Future.value(bytes);
  }

  Future<String> readAsString() {
    throw "unsupported operation";
  }

  Future<bool> exists() => new Future.value(bytes != null);
}
