// Copyright (c) 2024, 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.

// Bindings for `src/objective_c.h` etc.
// Regenerate bindings with `dart run tool/generate_code.dart`.

// coverage:ignore-file

// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import, unused_element, deprecated_member_use_from_same_package
@ffi.DefaultAsset('package:objective_c/objective_c.dylib')
library;

import 'dart:ffi' as ffi;

@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>(
  symbol: 'DOBJC_awaitWaiter',
)
external void awaitWaiter(ffi.Pointer<ffi.Void> waiter);

@ffi.Native<ffi.Void Function(Dart_FinalizableHandle, ffi.Handle)>(
  symbol: 'DOBJC_deleteFinalizableHandle',
)
external void deleteFinalizableHandle(
  Dart_FinalizableHandle handle,
  Object owner,
);

@ffi.Native<ffi.Void Function(ffi.Pointer<ObjCBlockImpl>)>(
  symbol: 'DOBJC_disposeObjCBlockWithClosure',
)
external void disposeObjCBlockWithClosure(ffi.Pointer<ObjCBlockImpl> block);

@ffi.Native<ffi.Pointer<DOBJC_Context> Function(ffi.Pointer<DOBJC_Context>)>(
  symbol: 'DOBJC_fillContext',
  isLeaf: true,
)
external ffi.Pointer<DOBJC_Context> fillContext(
  ffi.Pointer<DOBJC_Context> context,
);

/// Returns the MacOS/iOS version we're running on.
@ffi.Native<_Version Function()>(symbol: 'DOBJC_getOsVesion', isLeaf: true)
external _Version getOsVesion();

@ffi.Native<ffi.IntPtr Function(ffi.Pointer<ffi.Void>)>(
  symbol: 'DOBJC_initializeApi',
  isLeaf: true,
)
external int initializeApi(ffi.Pointer<ffi.Void> data);

@ffi.Native<ffi.Bool Function(ffi.Pointer<ObjCBlockImpl>)>(
  symbol: 'DOBJC_isValidBlock',
  isLeaf: true,
)
external bool isValidBlock(ffi.Pointer<ObjCBlockImpl> block);

@ffi.Native<ffi.Pointer<ffi.Bool> Function(ffi.Handle)>(
  symbol: 'DOBJC_newFinalizableBool',
)
external ffi.Pointer<ffi.Bool> newFinalizableBool(Object owner);

@ffi.Native<
  Dart_FinalizableHandle Function(ffi.Handle, ffi.Pointer<ObjCObjectImpl>)
>(symbol: 'DOBJC_newFinalizableHandle')
external Dart_FinalizableHandle newFinalizableHandle(
  Object owner,
  ffi.Pointer<ObjCObjectImpl> object,
);

@ffi.Native<ffi.Pointer<ffi.Void> Function()>(
  symbol: 'DOBJC_newWaiter',
  isLeaf: true,
)
external ffi.Pointer<ffi.Void> newWaiter();

@ffi.Native<
  ffi.Void Function(
    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
    ffi.Pointer<ffi.Void>,
  )
>(symbol: 'DOBJC_runOnMainThread', isLeaf: true)
external void runOnMainThread(
  ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>> fn,
  ffi.Pointer<ffi.Void> arg,
);

@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>(
  symbol: 'DOBJC_signalWaiter',
  isLeaf: true,
)
external void signalWaiter(ffi.Pointer<ffi.Void> waiter);

final class DOBJC_Context extends ffi.Struct {
  @ffi.Int64()
  external int version;

  external ffi.Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>
  newWaiter$1;

  external ffi.Pointer<
    ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>
  >
  awaitWaiter$1;

  external ffi.Pointer<
    ffi.NativeFunction<ffi.Pointer<_Dart_Isolate> Function()>
  >
  currentIsolate;

  external ffi.Pointer<
    ffi.NativeFunction<ffi.Void Function(ffi.Pointer<_Dart_Isolate>)>
  >
  enterIsolate;

  external ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> exitIsolate;

  external ffi.Pointer<ffi.NativeFunction<ffi.Int64 Function()>> getMainPortId;

  external ffi.Pointer<ffi.NativeFunction<ffi.Bool Function(ffi.Int64)>>
  getCurrentThreadOwnsIsolate;

  static ffi.Pointer<DOBJC_Context> $allocate(
    ffi.Allocator $allocator, {
    required int version,
    required ffi.Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>
    newWaiter$1,
    required ffi.Pointer<
      ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>
    >
    awaitWaiter$1,
    required ffi.Pointer<
      ffi.NativeFunction<ffi.Pointer<_Dart_Isolate> Function()>
    >
    currentIsolate,
    required ffi.Pointer<
      ffi.NativeFunction<ffi.Void Function(ffi.Pointer<_Dart_Isolate>)>
    >
    enterIsolate,
    required ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> exitIsolate,
    required ffi.Pointer<ffi.NativeFunction<ffi.Int64 Function()>>
    getMainPortId,
    required ffi.Pointer<ffi.NativeFunction<ffi.Bool Function(ffi.Int64)>>
    getCurrentThreadOwnsIsolate,
  }) => $allocator<DOBJC_Context>()
    ..ref.version = version
    ..ref.newWaiter$1 = newWaiter$1
    ..ref.awaitWaiter$1 = awaitWaiter$1
    ..ref.currentIsolate = currentIsolate
    ..ref.enterIsolate = enterIsolate
    ..ref.exitIsolate = exitIsolate
    ..ref.getMainPortId = getMainPortId
    ..ref.getCurrentThreadOwnsIsolate = getCurrentThreadOwnsIsolate;
}

typedef Dart_FinalizableHandle = ffi.Pointer<Dart_FinalizableHandle_>;

final class Dart_FinalizableHandle_ extends ffi.Opaque {}

const int ILLEGAL_PORT = 0;

final class ObjCBlockDesc extends ffi.Struct {
  @ffi.UnsignedLong()
  external int reserved;

  @ffi.UnsignedLong()
  external int size;

  external ffi.Pointer<
    ffi.NativeFunction<
      ffi.Void Function(ffi.Pointer<ffi.Void> dst, ffi.Pointer<ffi.Void> src)
    >
  >
  copy_helper;

  external ffi.Pointer<
    ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> src)>
  >
  dispose_helper;

  external ffi.Pointer<ffi.Char> signature;

  static ffi.Pointer<ObjCBlockDesc> $allocate(
    ffi.Allocator $allocator, {
    required int reserved,
    required int size,
    required ffi.Pointer<
      ffi.NativeFunction<
        ffi.Void Function(ffi.Pointer<ffi.Void> dst, ffi.Pointer<ffi.Void> src)
      >
    >
    copy_helper,
    required ffi.Pointer<
      ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> src)>
    >
    dispose_helper,
    required ffi.Pointer<ffi.Char> signature,
  }) => $allocator<ObjCBlockDesc>()
    ..ref.reserved = reserved
    ..ref.size = size
    ..ref.copy_helper = copy_helper
    ..ref.dispose_helper = dispose_helper
    ..ref.signature = signature;
}

final class ObjCBlockImpl extends ffi.Struct {
  external ffi.Pointer<ffi.Void> isa;

  @ffi.Int()
  external int flags;

  @ffi.Int()
  external int reserved;

  external ffi.Pointer<ffi.Void> invoke;

  external ffi.Pointer<ObjCBlockDesc> descriptor;

  external ffi.Pointer<ffi.Void> target;

  @ffi.Int64()
  external int dispose_port;

  static ffi.Pointer<ObjCBlockImpl> $allocate(
    ffi.Allocator $allocator, {
    required ffi.Pointer<ffi.Void> isa,
    required int flags,
    required int reserved,
    required ffi.Pointer<ffi.Void> invoke,
    required ffi.Pointer<ObjCBlockDesc> descriptor,
    required ffi.Pointer<ffi.Void> target,
    required int dispose_port,
  }) => $allocator<ObjCBlockImpl>()
    ..ref.isa = isa
    ..ref.flags = flags
    ..ref.reserved = reserved
    ..ref.invoke = invoke
    ..ref.descriptor = descriptor
    ..ref.target = target
    ..ref.dispose_port = dispose_port;
}

final class ObjCObjectImpl extends ffi.Opaque {}

final class _Dart_Isolate extends ffi.Opaque {}

final class _Version extends ffi.Struct {
  @ffi.Int()
  external int major;

  @ffi.Int()
  external int minor;

  @ffi.Int()
  external int patch;
}
