// Copyright (c) 2019, 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.
//
// This file generates the extension methods public API and the extension
// methods patch file for all integers, double, and float.
// The PointerPointer and PointerStruct extension are written by hand since
// those are not repetitive.

import 'dart:io';

import 'package:args/args.dart';

//
// Configuration.
//

const configuration = [
  Config("Int8", "int", "Int8List", 1),
  Config("Int16", "int", "Int16List", 2),
  Config("Int32", "int", "Int32List", 4),
  Config("Int64", "int", "Int64List", 8),
  Config("Uint8", "int", "Uint8List", 1),
  Config("Uint16", "int", "Uint16List", 2),
  Config("Uint32", "int", "Uint32List", 4),
  Config("Uint64", "int", "Uint64List", 8),
  Config("IntPtr", "int", kDoNotEmit, kIntPtrElementSize),
  Config("Float", "double", "Float32List", 4),
  Config("Double", "double", "Float64List", 8),
];

//
// Generator.
//

main(List<String> arguments) {
  final args = argParser().parse(arguments);
  Uri path = Uri.parse(args['path']);

  generate(path, "ffi.g.dart", generatePublicExtension);
  generate(path, "ffi_patch.g.dart", generatePatchExtension);
}

void generate(
    Uri path, String fileName, Function(StringBuffer, Config) generator) {
  final buffer = StringBuffer();
  generateHeader(buffer);
  configuration.forEach((Config c) => generator(buffer, c));
  generateFooter(buffer);

  final fullPath = path.resolve(fileName).path;
  File(fullPath).writeAsStringSync(buffer.toString());
  final fmtResult = Process.runSync(dartfmtPath().path, ["-w", fullPath]);
  if (fmtResult.exitCode != 0) {
    throw Exception(
        "Formatting failed:\n${fmtResult.stdout}\n${fmtResult.stderr}\n");
  }
  print("Generated $fullPath.");
}

void generateHeader(StringBuffer buffer) {
  final header = """
//
// The following code is generated, do not edit by hand.
//
// Code generated by `runtime/tools/ffi/sdk_lib_ffi_generator.dart`.
//

""";

  buffer.write(header);
}

void generatePublicExtension(StringBuffer buffer, Config config) {
  final nativeType = config.nativeType;
  final dartType = config.dartType;
  final typedListType = config.typedListType;
  final elementSize = config.elementSize;

  final storeTrunctateInt = """
  /// Note that ints which do not fit in `$nativeType` are truncated.
""";

  final storeTrunctateDouble = """
  /// Note that doubles stored into Pointer<`Float`> lose precision.
""";

  final storeTruncate =
      _isInt(nativeType) ? storeTrunctateInt : storeTrunctateDouble;

  final loadSignExtendInt = """
  /// Note that ints are signextended.
""";

  final loadSignExtend = _isInt(nativeType) ? loadSignExtendInt : "";

  final asTypedList = typedListType == kDoNotEmit
      ? ""
      : """
  /// Creates a typed list view backed by memory in the address space.
  ///
  /// The returned view will allow access to the memory range from `address`
  /// to `address + ${elementSize > 1 ? '$elementSize * ' : ''}length`.
  ///
  /// The user has to ensure the memory range is accessible while using the
  /// returned list.
  external $typedListType asTypedList(int length);
""";

  // TODO(dartdoc-bug): Use [] instead of ``, once issue
  // https://github.com/dart-lang/dartdoc/issues/2039 is fixed.
  buffer.write("""
/// Extension on [Pointer] specialized for the type argument [$nativeType].
extension ${nativeType}Pointer on Pointer<$nativeType> {
  /// Load a Dart value from this location.
  ///
  /// The value is automatically unmarshalled from its native representation.
$loadSignExtend  ///
  /// Note that `address` needs to be aligned to the size of `$nativeType`.
  external $dartType get value;

  /// Store a Dart value into this location.
  ///
  /// The `value` is automatically marshalled into its native representation.
$storeTruncate  ///
  /// Note that `address` needs to be aligned to the size of `$nativeType`.
  external void set value($dartType value);

  /// Load a Dart value from this location offset by `index`.
  ///
  /// The value is automatically unmarshalled from its native representation.
$loadSignExtend  ///
  /// Note that `address` needs to be aligned to the size of `$nativeType`.
  external $dartType operator [](int index);

  /// Store a Dart value into this location offset by `index`.
  ///
  /// The `value` is automatically marshalled into its native representation.
$storeTruncate  ///
  /// Note that `address` needs to be aligned to the size of `$nativeType`.
  external void operator []=(int index, $dartType value);

$asTypedList
}

""");
}

void generatePatchExtension(StringBuffer buffer, Config config) {
  final nativeType = config.nativeType;
  final dartType = config.dartType;
  final typedListType = config.typedListType;

  final asTypedList = typedListType == kDoNotEmit
      ? ""
      : """
  @patch
  $typedListType asTypedList(int elements) => _asExternalTypedData(this, elements);
""";

  buffer.write("""
extension ${nativeType}Pointer on Pointer<$nativeType> {
 @patch
  $dartType get value => _load$nativeType(this, 0);

  @patch
  set value($dartType value) => _store$nativeType(this, 0, value);

  @patch
  $dartType operator [](int index) => _load$nativeType(this, index);

  @patch
  operator []=(int index, $dartType value) => _store$nativeType(this, index, value);

$asTypedList
}

""");
}

void generateFooter(StringBuffer buffer) {
  final footer = """
//
// End of generated code.
//
""";

  buffer.write(footer);
}

//
// Helper functions.
//

bool _isInt(String type) => type.startsWith("Int") || type.startsWith("Uint");

final Uri _containingFolder = File.fromUri(Platform.script).parent.uri;

ArgParser argParser() {
  final parser = ArgParser(allowTrailingOptions: false);
  parser.addOption('path',
      abbr: 'p',
      help: 'Path to generate the files at.',
      defaultsTo: _containingFolder.toString());
  parser.addFlag('help', abbr: 'h', help: 'Display usage information.',
      callback: (help) {
    if (help) print(parser.usage);
  });
  return parser;
}

Uri dartfmtPath() {
  // TODO(dacoharkes): Use "../../../tools/sdks/dart-sdk/bin/dartfmt" when the
  // pinned fully supports extension methods.
  return Uri.parse("dartfmt");
}

class Config {
  final String nativeType;
  final String dartType;
  final String typedListType;
  final int elementSize;
  const Config(
      this.nativeType, this.dartType, this.typedListType, this.elementSize);
}

const String kDoNotEmit = "donotemit";
const int kIntPtrElementSize = -1;
