// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v10.0.1), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import
// ignore_for_file: avoid_relative_lib_imports
import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:file_selector_windows/src/messages.g.dart';

class _TestFileSelectorApiCodec extends StandardMessageCodec {
  const _TestFileSelectorApiCodec();
  @override
  void writeValue(WriteBuffer buffer, Object? value) {
    if (value is FileDialogResult) {
      buffer.putUint8(128);
      writeValue(buffer, value.encode());
    } else if (value is SelectionOptions) {
      buffer.putUint8(129);
      writeValue(buffer, value.encode());
    } else if (value is TypeGroup) {
      buffer.putUint8(130);
      writeValue(buffer, value.encode());
    } else {
      super.writeValue(buffer, value);
    }
  }

  @override
  Object? readValueOfType(int type, ReadBuffer buffer) {
    switch (type) {
      case 128:
        return FileDialogResult.decode(readValue(buffer)!);
      case 129:
        return SelectionOptions.decode(readValue(buffer)!);
      case 130:
        return TypeGroup.decode(readValue(buffer)!);
      default:
        return super.readValueOfType(type, buffer);
    }
  }
}

abstract class TestFileSelectorApi {
  static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
      TestDefaultBinaryMessengerBinding.instance;
  static const MessageCodec<Object?> codec = _TestFileSelectorApiCodec();

  FileDialogResult showOpenDialog(SelectionOptions options,
      String? initialDirectory, String? confirmButtonText);

  FileDialogResult showSaveDialog(
      SelectionOptions options,
      String? initialDirectory,
      String? suggestedName,
      String? confirmButtonText);

  static void setup(TestFileSelectorApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.FileSelectorApi.showOpenDialog', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        _testBinaryMessengerBinding!.defaultBinaryMessenger
            .setMockDecodedMessageHandler<Object?>(channel, null);
      } else {
        _testBinaryMessengerBinding!.defaultBinaryMessenger
            .setMockDecodedMessageHandler<Object?>(channel,
                (Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.FileSelectorApi.showOpenDialog was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final SelectionOptions? arg_options = (args[0] as SelectionOptions?);
          assert(arg_options != null,
              'Argument for dev.flutter.pigeon.FileSelectorApi.showOpenDialog was null, expected non-null SelectionOptions.');
          final String? arg_initialDirectory = (args[1] as String?);
          final String? arg_confirmButtonText = (args[2] as String?);
          final FileDialogResult output = api.showOpenDialog(
              arg_options!, arg_initialDirectory, arg_confirmButtonText);
          return <Object?>[output];
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.FileSelectorApi.showSaveDialog', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        _testBinaryMessengerBinding!.defaultBinaryMessenger
            .setMockDecodedMessageHandler<Object?>(channel, null);
      } else {
        _testBinaryMessengerBinding!.defaultBinaryMessenger
            .setMockDecodedMessageHandler<Object?>(channel,
                (Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.FileSelectorApi.showSaveDialog was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final SelectionOptions? arg_options = (args[0] as SelectionOptions?);
          assert(arg_options != null,
              'Argument for dev.flutter.pigeon.FileSelectorApi.showSaveDialog was null, expected non-null SelectionOptions.');
          final String? arg_initialDirectory = (args[1] as String?);
          final String? arg_suggestedName = (args[2] as String?);
          final String? arg_confirmButtonText = (args[3] as String?);
          final FileDialogResult output = api.showSaveDialog(arg_options!,
              arg_initialDirectory, arg_suggestedName, arg_confirmButtonText);
          return <Object?>[output];
        });
      }
    }
  }
}
