// 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:ffigen/src/code_generator.dart';
import 'package:meta/meta.dart';

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

/// A binding for C function.
///
/// For a C function -
/// ```c
/// int sum(int a, int b);
/// ```
/// The Generated dart code is -
/// ```dart
/// int sum(int a, int b) {
///   return _sum(a, b);
/// }
///
/// final _dart_sum _sum = _dylib.lookupFunction<_c_sum, _dart_sum>('sum');
///
/// typedef _c_sum = ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b);
///
/// typedef _dart_sum = int Function(int a, int b);
/// ```
class Func extends LookUpBinding {
  final String lookupSymbolName;
  final Type returnType;
  final List<Parameter> parameters;

  /// [lookupSymbolName], if not provided, takes the value of [name].
  Func({
    @required String name,
    String lookupSymbolName,
    String dartDoc,
    @required this.returnType,
    List<Parameter> parameters,
  })  : parameters = parameters ?? [],
        lookupSymbolName = lookupSymbolName ?? name,
        super(name: name, dartDoc: dartDoc) {
    for (var i = 0; i < this.parameters.length; i++) {
      if (this.parameters[i].name == null ||
          this.parameters[i].name.trim() == '') {
        this.parameters[i].name = 'arg$i';
      }
    }
  }

  List<Typedef> _typedefDependencies;
  @override
  List<Typedef> getTypedefDependencies(Writer w) {
    if (_typedefDependencies == null) {
      _typedefDependencies = <Typedef>[];

      /// Ensure name conflicts are resolved for [cType] and [dartType] typedefs.
      cType.name = _uniqueTypedefName(cType.name, w);
      dartType.name = _uniqueTypedefName(dartType.name, w);

      // Add typedef's required by parameters.
      for (final p in parameters) {
        final base = p.type.getBaseType();
        if (base.broadType == BroadType.NativeFunction) {
          // Resolve name conflicts in typedef's required by parameters before using.
          base.nativeFunc.name = _uniqueTypedefName(base.nativeFunc.name, w);
          _typedefDependencies.add(base.nativeFunc);
        }
      }
      // Add C function typedef.
      _typedefDependencies.add(cType);
      // Add Dart function typedef.
      _typedefDependencies.add(dartType);
    }
    return _typedefDependencies;
  }

  /// Checks if typedef name is unique in both top level and wrapper level.
  /// And only marks it as used at top-level.
  String _uniqueTypedefName(String name, Writer w) {
    final base = name;
    String uniqueName = name;
    int suffix = 0;
    while (w.topLevelUniqueNamer.isUsed(uniqueName) ||
        w.wrapperLevelUniqueNamer.isUsed(uniqueName)) {
      suffix++;
      uniqueName = base + suffix.toString();
    }
    w.topLevelUniqueNamer.markUsed(uniqueName);
    return uniqueName;
  }

  Typedef _cType, _dartType;
  Typedef get cType => _cType ??= Typedef(
        name: '_c_$name',
        returnType: returnType,
        parameters: parameters,
        typedefType: TypedefType.C,
      );
  Typedef get dartType => _dartType ??= Typedef(
        name: '_dart_$name',
        returnType: returnType,
        parameters: parameters,
        typedefType: TypedefType.Dart,
      );

  @override
  BindingString toBindingString(Writer w) {
    final s = StringBuffer();
    final enclosingFuncName = name;
    final funcVarName = w.wrapperLevelUniqueNamer.makeUnique('_$name');

    if (dartDoc != null) {
      s.write(makeDartDoc(dartDoc));
    }

    // Write enclosing function.
    s.write('${returnType.getDartType(w)} $enclosingFuncName(\n');
    for (final p in parameters) {
      s.write('  ${p.type.getDartType(w)} ${p.name},\n');
    }
    s.write(') {\n');
    s.write(
        "$funcVarName ??= ${w.dylibIdentifier}.lookupFunction<${cType.name},${dartType.name}>('$lookupSymbolName');\n");

    s.write('  return $funcVarName(\n');
    for (final p in parameters) {
      s.write('    ${p.name},\n');
    }
    s.write('  );\n');
    s.write('}\n');

    // Write function variable.
    s.write('${dartType.name} $funcVarName;\n\n');

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

/// Represents a Function's parameter.
class Parameter {
  String name;
  final Type type;

  Parameter({this.name, @required this.type});
}
