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

// @dart = 2.9

/// Conventions for paths:
///
/// - Use the [Uri] class for paths that may have the `file`, `dart` or
///   `package` scheme.  Never use [Uri] for relative paths.
/// - Use [String]s for all filenames and paths that have no scheme prefix.
/// - Never translate a `dart:` or `package:` URI into a `file:` URI, instead
///   translate it to a [String] if the file system path is needed.
/// - Only use [File] from dart:io at the last moment when it is needed.
///
library kernel;

import 'ast.dart';
import 'binary/ast_to_binary.dart';
import 'binary/ast_from_binary.dart';
import 'dart:io';
import 'text/ast_to_text.dart';

export 'ast.dart';

Component loadComponentFromBinary(String path, [Component component]) {
  List<int> bytes = new File(path).readAsBytesSync();
  return loadComponentFromBytes(bytes, component);
}

Component loadComponentFromBytes(List<int> bytes, [Component component]) {
  component ??= new Component();
  new BinaryBuilder(bytes).readComponent(component);
  return component;
}

Component loadComponentSourceFromBytes(List<int> bytes, [Component component]) {
  component ??= new Component();
  new BinaryBuilder(bytes).readComponentSource(component);
  return component;
}

Future writeComponentToBinary(Component component, String path) {
  IOSink sink;
  if (path == 'null' || path == 'stdout') {
    sink = stdout.nonBlocking;
  } else {
    sink = new File(path).openWrite();
  }

  Future future;
  try {
    new BinaryPrinter(sink).writeComponentFile(component);
  } finally {
    if (sink == stdout.nonBlocking) {
      future = sink.flush();
    } else {
      future = sink.close();
    }
  }

  return future;
}

List<int> writeComponentToBytes(Component component) {
  BytesSink sink = new BytesSink();
  new BinaryPrinter(sink).writeComponentFile(component);
  return sink.builder.toBytes();
}

void writeLibraryToText(Library library, {String path}) {
  StringBuffer buffer = new StringBuffer();
  new Printer(buffer).writeLibraryFile(library);
  if (path == null) {
    print(buffer);
  } else {
    new File(path).writeAsStringSync('$buffer');
  }
}

void writeComponentToText(Component component,
    {String path, bool showOffsets: false, bool showMetadata: false}) {
  StringBuffer buffer = new StringBuffer();
  new Printer(buffer, showOffsets: showOffsets, showMetadata: showMetadata)
      .writeComponentFile(component);
  if (path == null) {
    print(buffer);
  } else {
    new File(path).writeAsStringSync('$buffer');
  }
}
