// Copyright (c) 2020, 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 'package:meta/meta.dart';

import 'binding.dart';
import 'binding_string.dart';
import 'type.dart';
import 'writer.dart';

/// A binding for C Struct.
///
/// For a C structure -
/// ```c
/// struct C {
///   int a;
///   double b;
///   int c;
/// };
/// ```
/// The generated dart code is -
/// ```dart
/// class Struct extends ffi.Struct{
///  @ffi.Int32()
///  int a;
///
///  @ffi.Double()
///  double b;
///
///  @ffi.Uint8()
///  int c;
///
/// }
/// ```
class Struc extends Binding {
  final List<Member> members;

  Struc({
    @required String name,
    String dartDoc,
    List<Member> members,
  })  : members = members ?? [],
        super(name: name, dartDoc: dartDoc);

  @override
  BindingString toBindingString(Writer w) {
    final s = StringBuffer();

    if (dartDoc != null) {
      s.write('/// ');
      s.writeAll(dartDoc.split('\n'), '\n/// ');
      s.write('\n');
    }

    final helpers = <ArrayHelper>[];

    // Write class declaration.
    s.write('class $name extends ${w.ffiLibraryPrefix}.Struct{\n');
    for (final m in members) {
      if (m.type.broadType == BroadType.ConstantArray) {
        // TODO(5): Remove array helpers when inline array support arives.
        final arrayHelper = ArrayHelper(
          helperClassName: '_ArrayHelper_${name}_${m.name}',
          elementType: m.type.elementType,
          length: 3,
          name: m.name,
          structName: name,
          elementNamePrefix: '_${m.name}_item_',
        );
        s.write(arrayHelper.declarationString(w));
        helpers.add(arrayHelper);
      } else {
        const depth = '  ';
        if (m.dartDoc != null) {
          s.write(depth + '/// ');
          s.writeAll(m.dartDoc.split('\n'), '\n' + depth + '/// ');
          s.write('\n');
        }
        if (m.type.isPrimitive) {
          s.write('$depth@${m.type.getCType(w)}()\n');
        }
        s.write('$depth${m.type.getDartType(w)} ${m.name};\n\n');
      }
    }
    s.write('}\n\n');

    for (final helper in helpers) {
      s.write(helper.helperClassString(w));
    }

    return BindingString(type: BindingStringType.struc, string: s.toString());
  }
}

class Member {
  final String dartDoc;
  final String name;
  final Type type;

  const Member({this.name, this.type, this.dartDoc});
}

// Helper bindings for struct array.
class ArrayHelper {
  final Type elementType;
  final int length;
  final String structName;

  final String name;
  final String helperClassName;
  final String elementNamePrefix;

  ArrayHelper({
    @required this.elementType,
    @required this.length,
    @required this.structName,
    @required this.name,
    @required this.helperClassName,
    @required this.elementNamePrefix,
  });

  /// Create declaration binding, added inside the struct binding.
  String declarationString(Writer w) {
    final s = StringBuffer();
    final arrayDartType = elementType.getDartType(w);
    final arrayCType = elementType.getCType(w);

    for (var i = 0; i < length; i++) {
      if (elementType.isPrimitive) {
        s.write('  @${arrayCType}()\n');
      }
      s.write('  ${arrayDartType} ${elementNamePrefix}$i;\n');
    }

    s.write('/// helper for array, supports `[]` operator\n');
    s.write(
        '$helperClassName get $name => ${helperClassName}(this, $length);\n');

    return s.toString();
  }

  /// Creates an array helper binding for struct array.
  String helperClassString(Writer w) {
    final s = StringBuffer();

    final arrayType = elementType.getDartType(w);

    s.write('/// Helper for array $name in struct $structName\n');

    // Write class declaration.
    s.write('class $helperClassName{\n');
    s.write('final $structName _struct;\n');
    s.write('final int length;\n');
    s.write('$helperClassName(this._struct, this.length);\n');

    // Override []= operator.
    s.write('void operator []=(int index, $arrayType value) {\n');
    s.write('switch(index) {\n');
    for (var i = 0; i < length; i++) {
      s.write('case $i:\n');
      s.write('  _struct.${elementNamePrefix}$i = value;\n');
      s.write('  break;\n');
    }
    s.write('default:\n');
    s.write(
        "  throw RangeError('Index \$index must be in the range [0..${length - 1}].');");
    s.write('}\n');
    s.write('}\n');

    // Override [] operator.
    s.write('$arrayType operator [](int index) {\n');
    s.write('switch(index) {\n');
    for (var i = 0; i < length; i++) {
      s.write('case $i:\n');
      s.write('  return _struct.${elementNamePrefix}$i;\n');
    }
    s.write('default:\n');
    s.write(
        "  throw RangeError('Index \$index must be in the range [0..${length - 1}].');");
    s.write('}\n');
    s.write('}\n');

    // Override toString().
    s.write('@override\n');
    s.write('String toString() {\n');
    s.write("if (length == 0) return '[]';\n");
    s.write("final sb = StringBuffer('[');\n");
    s.write('sb.write(this[0]);\n');
    s.write('for (var i = 1; i < length; i++) {\n');
    s.write("  sb.write(',');\n");
    s.write('  sb.write(this[i]);');
    s.write('}\n');
    s.write("sb.write(']');");
    s.write('return sb.toString();\n');
    s.write('}\n');

    s.write('}\n\n');
    return s.toString();
  }
}
