// 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.md file.

// TODO(ahe): Copied from closure_conversion branch of kernel, remove this file
// when closure_conversion is merged with master.

library fasta.testing.kernel_chain;

import 'dart:async' show Future;

import 'dart:io' show Directory, File, IOSink;

import 'dart:typed_data' show Uint8List;

import 'package:kernel/ast.dart'
    show Component, Field, Library, ListLiteral, StringLiteral;

import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;

import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;

import 'package:kernel/error_formatter.dart' show ErrorFormatter;

import 'package:kernel/kernel.dart' show loadComponentFromBinary;

import 'package:kernel/naive_type_checker.dart' show StrongModeTypeChecker;

import 'package:kernel/target/targets.dart' show Target;

import 'package:kernel/text/ast_to_text.dart' show Printer;

import 'package:testing/testing.dart'
    show ChainContext, Result, StdioProcess, Step, TestDescription;

import '../../api_prototype/front_end.dart';

import '../../base/processed_options.dart' show ProcessedOptions;

import '../../compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;

import '../compiler_context.dart';

import '../kernel/verifier.dart' show verifyComponent;

class Print extends Step<Component, Component, ChainContext> {
  const Print();

  String get name => "print";

  Future<Result<Component>> run(Component component, _) async {
    StringBuffer sb = new StringBuffer();
    for (Library library in component.libraries) {
      Printer printer = new Printer(sb);
      if (library.importUri.scheme != "dart" &&
          library.importUri.scheme != "package") {
        printer.writeLibraryFile(library);
      }
    }
    print("$sb");
    return pass(component);
  }
}

class Verify extends Step<Component, Component, ChainContext> {
  final bool fullCompile;

  const Verify(this.fullCompile);

  String get name => "verify";

  Future<Result<Component>> run(
      Component component, ChainContext context) async {
    var options = new ProcessedOptions(new CompilerOptions());
    return await CompilerContext.runWithOptions(options, (_) async {
      var errors = verifyComponent(component,
          isOutline: !fullCompile, skipPlatform: true);
      if (errors.isEmpty) {
        return pass(component);
      } else {
        return new Result<Component>(
            null, context.expectationSet["VerificationError"], errors, null);
      }
    });
  }
}

class TypeCheck extends Step<Component, Component, ChainContext> {
  const TypeCheck();

  String get name => "typeCheck";

  Future<Result<Component>> run(
      Component component, ChainContext context) async {
    var errorFormatter = new ErrorFormatter();
    var checker =
        new StrongModeTypeChecker(errorFormatter, component, ignoreSdk: true);
    checker.checkComponent(component);
    if (errorFormatter.numberOfFailures == 0) {
      return pass(component);
    } else {
      errorFormatter.failures.forEach(print);
      print('------- Found ${errorFormatter.numberOfFailures} errors -------');
      return new Result<Component>(
          null,
          context.expectationSet["TypeCheckError"],
          '${errorFormatter.numberOfFailures} type errors',
          null);
    }
  }
}

class MatchExpectation extends Step<Component, Component, ChainContext> {
  final String suffix;

  // TODO(ahe): This is true by default which doesn't match well with the class
  // name.
  final bool updateExpectations;

  const MatchExpectation(this.suffix, {this.updateExpectations: false});

  String get name => "match expectations";

  Future<Result<Component>> run(Component component, _) async {
    Library library = component.libraries
        .firstWhere((Library library) => library.importUri.scheme != "dart");
    Uri uri = library.importUri;
    Uri base = uri.resolve(".");
    Uri dartBase = Uri.base;
    StringBuffer buffer = new StringBuffer();
    for (Field field in library.fields) {
      if (field.name.name != "#errors") continue;
      ListLiteral list = field.initializer;
      buffer.write("// Errors:");
      for (StringLiteral string in list.expressions) {
        buffer.write("\n//");
        for (String line in string.value.split("\n")) {
          buffer.write("\n// $line");
        }
      }
      buffer.write("\n\n");
    }
    new ErrorPrinter(buffer).writeLibraryFile(library);
    String actual = "$buffer".replaceAll("$base", "org-dartlang-testcase:///");
    actual = actual.replaceAll("$dartBase", "org-dartlang-testcase-sdk:///");
    actual = actual.replaceAll("\\n", "\n");
    File expectedFile = new File("${uri.toFilePath()}$suffix");
    if (await expectedFile.exists()) {
      String expected = await expectedFile.readAsString();
      if (expected.trim() != actual.trim()) {
        if (!updateExpectations) {
          String diff = await runDiff(expectedFile.uri, actual);
          return fail(null, "$uri doesn't match ${expectedFile.uri}\n$diff");
        }
      } else {
        return pass(component);
      }
    }
    if (updateExpectations) {
      await openWrite(expectedFile.uri, (IOSink sink) {
        sink.writeln(actual.trim());
      });
      return pass(component);
    } else {
      return fail(component, """
Please create file ${expectedFile.path} with this content:
$actual""");
    }
  }
}

class WriteDill extends Step<Component, Uri, ChainContext> {
  const WriteDill();

  String get name => "write .dill";

  Future<Result<Uri>> run(Component component, _) async {
    Directory tmp = await Directory.systemTemp.createTemp();
    Uri uri = tmp.uri.resolve("generated.dill");
    File generated = new File.fromUri(uri);
    IOSink sink = generated.openWrite();
    try {
      try {
        new BinaryPrinter(sink).writeComponentFile(component);
      } finally {
        component.unbindCanonicalNames();
      }
    } catch (e, s) {
      return fail(uri, e, s);
    } finally {
      print("Wrote `${generated.path}`");
      await sink.close();
    }
    return pass(uri);
  }
}

class ReadDill extends Step<Uri, Uri, ChainContext> {
  const ReadDill();

  String get name => "read .dill";

  Future<Result<Uri>> run(Uri uri, _) async {
    try {
      loadComponentFromBinary(uri.toFilePath());
    } catch (e, s) {
      return fail(uri, e, s);
    }
    return pass(uri);
  }
}

class Copy extends Step<Component, Component, ChainContext> {
  const Copy();

  String get name => "copy component";

  Future<Result<Component>> run(Component component, _) async {
    BytesCollector sink = new BytesCollector();
    new BinaryPrinter(sink).writeComponentFile(component);
    component.unbindCanonicalNames();
    Uint8List bytes = sink.collect();
    new BinaryBuilder(bytes).readComponent(component);
    return pass(component);
  }
}

/// A `package:testing` step that runs the `package:front_end` compiler to
/// generate a kernel component for an individual file.
///
/// Most options are hard-coded, but if necessary they could be moved to the
/// [CompileContext] object in the future.
class Compile extends Step<TestDescription, Component, CompileContext> {
  const Compile();

  String get name => "fasta compilation";

  Future<Result<Component>> run(
      TestDescription description, CompileContext context) async {
    Result<Component> result;
    reportError(CompilationMessage error) {
      result ??= fail(null, error.message);
    }

    Uri sdk = Uri.base.resolve("sdk/");
    var options = new CompilerOptions()
      ..sdkRoot = sdk
      ..compileSdk = true
      ..packagesFileUri = Uri.base.resolve('.packages')
      ..strongMode = context.strongMode
      ..onError = reportError;
    if (context.target != null) {
      options.target = context.target;
      // Do not link platform.dill, but recompile the platform libraries. This
      // ensures that if target defines extra libraries that those get included
      // too.
    } else {
      options.linkedDependencies = [
        computePlatformBinariesLocation().resolve("vm_platform.dill"),
      ];
    }
    Component p = await kernelForProgram(description.uri, options);
    return result ??= pass(p);
  }
}

abstract class CompileContext implements ChainContext {
  bool get strongMode;
  Target get target;
}

class BytesCollector implements Sink<List<int>> {
  final List<List<int>> lists = <List<int>>[];

  int length = 0;

  void add(List<int> data) {
    lists.add(data);
    length += data.length;
  }

  Uint8List collect() {
    Uint8List result = new Uint8List(length);
    int offset = 0;
    for (List<int> list in lists) {
      result.setRange(offset, offset += list.length, list);
    }
    lists.clear();
    length = 0;
    return result;
  }

  void close() {}
}

Future<String> runDiff(Uri expected, String actual) async {
  StdioProcess process = await StdioProcess.run(
      "git", <String>["diff", "--no-index", "-u", expected.toFilePath(), "-"],
      input: actual, runInShell: true);
  return process.output;
}

Future<void> openWrite(Uri uri, f(IOSink sink)) async {
  IOSink sink = new File.fromUri(uri).openWrite();
  try {
    await f(sink);
  } finally {
    await sink.close();
  }
  print("Wrote $uri");
}

class ErrorPrinter extends Printer {
  ErrorPrinter(StringSink sink, {Object importTable, Object metadata})
      : super(sink, importTable: importTable, metadata: metadata);

  ErrorPrinter._inner(ErrorPrinter parent, Object importTable, Object metadata)
      : super(parent.sink,
            importTable: importTable,
            metadata: metadata,
            syntheticNames: parent.syntheticNames,
            annotator: parent.annotator,
            showExternal: parent.showExternal,
            showOffsets: parent.showOffsets,
            showMetadata: parent.showMetadata);

  @override
  ErrorPrinter createInner(importTable, metadata) {
    return new ErrorPrinter._inner(this, importTable, metadata);
  }

  @override
  visitField(Field node) {
    if (node.name.name != "#errors") {
      super.visitField(node);
    }
  }
}
