// 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 InternalCompilerResult, 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: options
              ..packagesFileUri ??= Uri.base.resolve(".packages")
              ..linkedDependencies = <Uri>[
                computePlatformBinariesLocation(forceBuildDir: true)
                    .resolve("vm_platform_strong.dill")
              ]
              ..fileSystem = (new FileBackedMemoryFileSystem()
                ..entities[mainUri.path] =
                    (new MemoryFileSystemEntity(mainUri)..bytes = <int>[])),
            inputs: <Uri>[mainUri]);

  Future<Null> compile(String source) {
    defineSource(mainUri.path, source);
    return CompilerContext.runWithOptions(options,
        (CompilerContext context) async {
      (await context.options.loadSdkSummary(null))?.computeCanonicalNames();
      InternalCompilerResult result = await generateKernelInternal();
      result?.component?.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);
}
