// 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 '../code_generator.dart';
import '../config_provider/public_ast.dart' as public_ast;
import '../context.dart';
import '../header_parser/sub_parsers/api_availability.dart';
import '../visitor/ast.dart';
import 'binding_string.dart';
import 'local_variables.dart';
import 'scope.dart';
import 'utils.dart';
import 'writer.dart';

/// A binding for C function.
///
/// For example, take the following C function.
///
/// ```c
/// int sum(int a, int b);
/// ```
///
/// The generated Dart code for this function (without `FfiNative`) is as
/// follows.
///
/// ```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);
/// ```
///
/// When using `Native`, the code is as follows.
///
/// ```dart
/// @ffi.Native<ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b)>('sum')
/// external int sum(int a, int b);
/// ```
class Func extends LookUpBinding with HasLocalScope {
  final FunctionType functionType;
  final bool exposeSymbolAddress;
  final bool exposeFunctionTypedefs;
  final bool isLeaf;
  final bool objCReturnsRetained;
  final bool useNameForLookup;
  final bool recordUse;
  final ApiAvailability? apiAvailability;

  @override
  final bool loadFromNativeAsset;

  /// The symbol for the internal function or method name, used for record use
  /// mapping and avoiding collisions.
  Symbol? funcVarSymbol;

  bool get needsWrapper => !functionType.sameDartAndFfiDartType && !isInternal;

  /// Contains typealias for function type if [exposeFunctionTypedefs] is true.
  Typealias? _exposedFunctionTypealias;

  bool isIncluded = false;

  /// [originalName] is looked up in dynamic library, if not
  /// provided, takes the value of [name].
  Func({
    super.usr,
    required String name,
    super.originalName,
    super.dartDoc,
    required Type returnType,
    List<Parameter> parameters = const [],
    List<Parameter> varArgParameters = const [],
    this.exposeSymbolAddress = false,
    this.exposeFunctionTypedefs = false,
    this.isLeaf = false,
    this.objCReturnsRetained = false,
    this.useNameForLookup = false,
    this.recordUse = false,
    super.isInternal,
    this.loadFromNativeAsset = false,
    this.apiAvailability,
  }) : functionType = FunctionType(
         returnType: returnType,
         parameters: parameters,
         varArgParameters: varArgParameters,
       ),
       super(symbol: Symbol(name, SymbolKind.method)) {
    for (var i = 0; i < functionType.parameters.length; i++) {
      if (functionType.parameters[i].symbol.oldName.isEmpty) {
        functionType.parameters[i].symbol = Symbol('arg$i', SymbolKind.field);
      }
    }

    // Get function name with first letter in upper case.
    final upperCaseName = name[0].toUpperCase() + name.substring(1);
    if (exposeFunctionTypedefs) {
      _exposedFunctionTypealias = Typealias(
        name: upperCaseName,
        type: functionType,
        genFfiDartType: true,
        isInternal: true,
      );
    }
  }

  @override
  public_ast.AstNode? toPublicAstNode() => public_ast.Func(this);

  void fillFuncVarSymbol() {
    funcVarSymbol ??= Symbol('_${symbol.oldName}', SymbolKind.method);
  }

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

    s.write(makeDartDoc(dartDoc));
    final deprecatedAnnotation = apiAvailability?.deprecatedAnnotation;
    if (deprecatedAnnotation != null) {
      s.write('$deprecatedAnnotation\n');
    }

    final context = w.context;
    final cType =
        _exposedFunctionTypealias?.getCType(context) ??
        functionType.getCType(context, writeArgumentNames: false);
    final dartType =
        _exposedFunctionTypealias?.getFfiDartType(context) ??
        functionType.getFfiDartType(context, writeArgumentNames: false);
    final needsWrapper = !functionType.sameDartAndFfiDartType && !isInternal;

    final funcVarName = funcVarSymbol!.name;
    final ffiReturnType = functionType.returnType.getFfiDartType(context);
    final ffiArgDeclString = functionType.dartTypeParameters
        .map((p) => '${p.type.getFfiDartType(context)} ${p.name},\n')
        .join('');
    final lookupName = useNameForLookup ? name : originalName;

    final String dartReturnType;
    final String dartArgDeclString;
    final String funcImplCall;
    final localVars = LocalVariables(localScope);

    if (needsWrapper) {
      dartReturnType = functionType.returnType.getDartType(context);
      dartArgDeclString = functionType.dartTypeParameters
          .map((p) => '${p.type.getDartType(context)} ${p.name},\n')
          .join('');

      final argString = functionType.dartTypeParameters
          .map((p) {
            final type = p.type.convertDartTypeToFfiDartType(
              context,
              p.name,
              objCRetain: p.objCConsumed,
              objCAutorelease: false,
              localVariables: localVars,
            );
            return '$type,\n';
          })
          .join('');
      funcImplCall = functionType.returnType.convertFfiDartTypeToDartType(
        context,
        '$funcVarName($argString)',
        objCRetain: !objCReturnsRetained,
      );
    } else {
      dartReturnType = ffiReturnType;
      dartArgDeclString = ffiArgDeclString;
      final argString = functionType.dartTypeParameters
          .map((p) => '${p.name},\n')
          .join('');
      funcImplCall = '$funcVarName($argString)';
    }

    if (recordUse) {
      final metaPrefix = context.libs.prefix(metaImport);
      s.writeln('@$metaPrefix.RecordUse()');
    }

    if (loadFromNativeAsset) {
      final nativeFuncName = needsWrapper ? funcVarName : enclosingFuncName;
      final nativeAnnotation = makeNativeAnnotation(
        w,
        nativeType: cType,
        dartName: nativeFuncName,
        nativeSymbolName: lookupName,
        isLeaf: isLeaf,
      );
      s.write('''
$nativeAnnotation
external $ffiReturnType $nativeFuncName($ffiArgDeclString);

''');
      if (needsWrapper) {
        s.write('''
$dartReturnType $enclosingFuncName($dartArgDeclString) {
  ${localVars.generateDeclarations()}
  return $funcImplCall;
}

''');
      }

      if (exposeSymbolAddress) {
        // Add to SymbolAddress in writer.
        w.symbolAddressWriter.addNativeSymbol(
          type:
              '${context.libs.prefix(ffiImport)}.Pointer<'
              '${context.libs.prefix(ffiImport)}.NativeFunction<$cType>>',
          name: name,
        );
      }
    } else {
      final funcPointerName = context.rootScope.addPrivate('_${name}Ptr');
      final isLeafString = isLeaf ? 'isLeaf:true' : '';

      // Write enclosing function.
      s.write('''
$dartReturnType $enclosingFuncName($dartArgDeclString) {
  ${localVars.generateDeclarations()}
  return $funcImplCall;
}

''');

      if (exposeSymbolAddress) {
        // Add to SymbolAddress in writer.
        w.symbolAddressWriter.addSymbol(
          type:
              '${context.libs.prefix(ffiImport)}.Pointer<'
              '${context.libs.prefix(ffiImport)}.NativeFunction<$cType>>',
          name: name,
          ptrName: funcPointerName,
        );
      }

      // Write function pointer.
      final lookupStr = Namer.stringLiteral(lookupName);
      final lookupFn = context.extraSymbols.lookupFuncName!.name;
      s.write('''
late final $funcPointerName = $lookupFn<
    ${context.libs.prefix(ffiImport)}.NativeFunction<$cType>>('$lookupStr');
late final $funcVarName = $funcPointerName.asFunction<$dartType>($isLeafString);

''');
    }

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

  @override
  void visitChildren(Visitor visitor) {
    super.visitChildren(visitor);
    visitor.visit(funcVarSymbol);
    visitor.visit(functionType);
    visitor.visit(_exposedFunctionTypealias);
    visitor.visit(ffiImport);
    if (recordUse) {
      visitor.visit(metaImport);
    }
    if (loadFromNativeAsset && exposeSymbolAddress) {
      visitor.visit(selfImport);
    }
  }

  @override
  void visit(Visitation visitation) => visitation.visitFunc(this);

  (String, String)? get recordUseMapping => recordUse
      ? (
          needsWrapper ? funcVarSymbol!.name : name,
          useNameForLookup ? name : originalName,
        )
      : null;
}

/// Extension on [Iterable<Func>] to generate record use mapping.
extension FuncRecordUse on Iterable<Func> {
  Map<String, String> toRecordUseMap() {
    return {
      for (final mapping in map((f) => f.recordUseMapping).nonNulls)
        mapping.$1: mapping.$2,
    };
  }
}

/// Represents a Parameter, used in [Func], [Typealias], [ObjCMethod], and
/// [ObjCBlock].
class Parameter extends AstNode {
  final String originalName;
  Type type;
  final bool objCConsumed;

  Symbol symbol;
  String get name => symbol.name;

  Parameter._({
    required this.originalName,
    required this.symbol,
    required Type type,
    required this.objCConsumed,
  }) : // A [NativeFunc] is wrapped with a pointer because this is a shorthand
       // used in C for Pointer to function.
       type = type.typealiasType is NativeFunc ? PointerType(type) : type;

  Parameter({
    String? name,
    String? originalName,
    required Type type,
    bool objCConsumed = false,
  }) : this._(
         originalName: originalName ?? name ?? '',
         symbol: Symbol(name ?? originalName ?? '', SymbolKind.field),
         type: type,
         objCConsumed: objCConsumed,
       );

  String getNativeType(
    Context context, {
    String varName = '',
    bool withAttr = true,
  }) =>
      '${type.getNativeType(context, varName: varName)}'
      '${withAttr && objCConsumed ? ' __attribute__((ns_consumed))' : ''}';

  @override
  String toString() => '$type $symbol';

  @override
  void visitChildren(Visitor visitor) {
    super.visitChildren(visitor);
    visitor.visit(symbol);
    visitor.visit(type);
  }

  Parameter clone() => Parameter._(
    originalName: originalName,
    symbol: symbol.clone(),
    type: type,
    objCConsumed: objCConsumed,
  );

  bool get isNullable => type.typealiasType is ObjCNullable;
}
