// 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.

import 'dart:async';
import 'dart:math';

import 'package:async/async.dart';
import 'package:camera_platform_interface/camera_platform_interface.dart';
import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart';
import 'package:camera_platform_interface/src/utils/utils.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import '../utils/method_channel_mock.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('$MethodChannelCamera', () {
    group('Creation, Initialization & Disposal Tests', () {
      test('Should send creation data and receive back a camera id', () async {
        // Arrange
        final MethodChannelMock cameraMockChannel = MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'create': <String, dynamic>{
                'cameraId': 1,
                'imageFormatGroup': 'unknown',
              }
            });
        final MethodChannelCamera camera = MethodChannelCamera();

        // Act
        final int cameraId = await camera.createCamera(
          const CameraDescription(
              name: 'Test',
              lensDirection: CameraLensDirection.back,
              sensorOrientation: 0),
          ResolutionPreset.high,
        );

        // Assert
        expect(cameraMockChannel.log, <Matcher>[
          isMethodCall(
            'create',
            arguments: <String, Object?>{
              'cameraName': 'Test',
              'resolutionPreset': 'high',
              'enableAudio': false
            },
          ),
        ]);
        expect(cameraId, 1);
      });

      test(
          'Should throw CameraException when create throws a PlatformException',
          () {
        // Arrange
        MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'create': PlatformException(
                code: 'TESTING_ERROR_CODE',
                message: 'Mock error message used during testing.',
              )
            });
        final MethodChannelCamera camera = MethodChannelCamera();

        // Act
        expect(
          () => camera.createCamera(
            const CameraDescription(
              name: 'Test',
              lensDirection: CameraLensDirection.back,
              sensorOrientation: 0,
            ),
            ResolutionPreset.high,
          ),
          throwsA(
            isA<CameraException>()
                .having(
                    (CameraException e) => e.code, 'code', 'TESTING_ERROR_CODE')
                .having((CameraException e) => e.description, 'description',
                    'Mock error message used during testing.'),
          ),
        );
      });

      test(
          'Should throw CameraException when create throws a PlatformException',
          () {
        // Arrange
        MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'create': PlatformException(
                code: 'TESTING_ERROR_CODE',
                message: 'Mock error message used during testing.',
              )
            });
        final MethodChannelCamera camera = MethodChannelCamera();

        // Act
        expect(
          () => camera.createCamera(
            const CameraDescription(
              name: 'Test',
              lensDirection: CameraLensDirection.back,
              sensorOrientation: 0,
            ),
            ResolutionPreset.high,
          ),
          throwsA(
            isA<CameraException>()
                .having(
                    (CameraException e) => e.code, 'code', 'TESTING_ERROR_CODE')
                .having((CameraException e) => e.description, 'description',
                    'Mock error message used during testing.'),
          ),
        );
      });

      test(
        'Should throw CameraException when initialize throws a PlatformException',
        () {
          // Arrange
          MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'initialize': PlatformException(
                code: 'TESTING_ERROR_CODE',
                message: 'Mock error message used during testing.',
              )
            },
          );
          final MethodChannelCamera camera = MethodChannelCamera();

          // Act
          expect(
            () => camera.initializeCamera(0),
            throwsA(
              isA<CameraException>()
                  .having((CameraException e) => e.code, 'code',
                      'TESTING_ERROR_CODE')
                  .having(
                    (CameraException e) => e.description,
                    'description',
                    'Mock error message used during testing.',
                  ),
            ),
          );
        },
      );

      test('Should send initialization data', () async {
        // Arrange
        final MethodChannelMock cameraMockChannel = MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'create': <String, dynamic>{
                'cameraId': 1,
                'imageFormatGroup': 'unknown',
              },
              'initialize': null
            });
        final MethodChannelCamera camera = MethodChannelCamera();
        final int cameraId = await camera.createCamera(
          const CameraDescription(
            name: 'Test',
            lensDirection: CameraLensDirection.back,
            sensorOrientation: 0,
          ),
          ResolutionPreset.high,
        );

        // Act
        final Future<void> initializeFuture = camera.initializeCamera(cameraId);
        camera.cameraEventStreamController.add(CameraInitializedEvent(
          cameraId,
          1920,
          1080,
          ExposureMode.auto,
          true,
          FocusMode.auto,
          true,
        ));
        await initializeFuture;

        // Assert
        expect(cameraId, 1);
        expect(cameraMockChannel.log, <Matcher>[
          anything,
          isMethodCall(
            'initialize',
            arguments: <String, Object?>{
              'cameraId': 1,
              'imageFormatGroup': 'unknown',
            },
          ),
        ]);
      });

      test('Should send a disposal call on dispose', () async {
        // Arrange
        final MethodChannelMock cameraMockChannel = MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'create': <String, dynamic>{'cameraId': 1},
              'initialize': null,
              'dispose': <String, dynamic>{'cameraId': 1}
            });

        final MethodChannelCamera camera = MethodChannelCamera();
        final int cameraId = await camera.createCamera(
          const CameraDescription(
            name: 'Test',
            lensDirection: CameraLensDirection.back,
            sensorOrientation: 0,
          ),
          ResolutionPreset.high,
        );
        final Future<void> initializeFuture = camera.initializeCamera(cameraId);
        camera.cameraEventStreamController.add(CameraInitializedEvent(
          cameraId,
          1920,
          1080,
          ExposureMode.auto,
          true,
          FocusMode.auto,
          true,
        ));
        await initializeFuture;

        // Act
        await camera.dispose(cameraId);

        // Assert
        expect(cameraId, 1);
        expect(cameraMockChannel.log, <Matcher>[
          anything,
          anything,
          isMethodCall(
            'dispose',
            arguments: <String, Object?>{'cameraId': 1},
          ),
        ]);
      });
    });

    group('Event Tests', () {
      late MethodChannelCamera camera;
      late int cameraId;
      setUp(() async {
        MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{
            'create': <String, dynamic>{'cameraId': 1},
            'initialize': null
          },
        );
        camera = MethodChannelCamera();
        cameraId = await camera.createCamera(
          const CameraDescription(
            name: 'Test',
            lensDirection: CameraLensDirection.back,
            sensorOrientation: 0,
          ),
          ResolutionPreset.high,
        );
        final Future<void> initializeFuture = camera.initializeCamera(cameraId);
        camera.cameraEventStreamController.add(CameraInitializedEvent(
          cameraId,
          1920,
          1080,
          ExposureMode.auto,
          true,
          FocusMode.auto,
          true,
        ));
        await initializeFuture;
      });

      test('Should receive initialized event', () async {
        // Act
        final Stream<CameraInitializedEvent> eventStream =
            camera.onCameraInitialized(cameraId);
        final StreamQueue<CameraInitializedEvent> streamQueue =
            StreamQueue<CameraInitializedEvent>(eventStream);

        // Emit test events
        final CameraInitializedEvent event = CameraInitializedEvent(
          cameraId,
          3840,
          2160,
          ExposureMode.auto,
          true,
          FocusMode.auto,
          true,
        );
        await camera.handleCameraMethodCall(
            MethodCall('initialized', event.toJson()), cameraId);

        // Assert
        expect(await streamQueue.next, event);

        // Clean up
        await streamQueue.cancel();
      });

      test('Should receive resolution changes', () async {
        // Act
        final Stream<CameraResolutionChangedEvent> resolutionStream =
            camera.onCameraResolutionChanged(cameraId);
        final StreamQueue<CameraResolutionChangedEvent> streamQueue =
            StreamQueue<CameraResolutionChangedEvent>(resolutionStream);

        // Emit test events
        final CameraResolutionChangedEvent fhdEvent =
            CameraResolutionChangedEvent(cameraId, 1920, 1080);
        final CameraResolutionChangedEvent uhdEvent =
            CameraResolutionChangedEvent(cameraId, 3840, 2160);
        await camera.handleCameraMethodCall(
            MethodCall('resolution_changed', fhdEvent.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('resolution_changed', uhdEvent.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('resolution_changed', fhdEvent.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('resolution_changed', uhdEvent.toJson()), cameraId);

        // Assert
        expect(await streamQueue.next, fhdEvent);
        expect(await streamQueue.next, uhdEvent);
        expect(await streamQueue.next, fhdEvent);
        expect(await streamQueue.next, uhdEvent);

        // Clean up
        await streamQueue.cancel();
      });

      test('Should receive camera closing events', () async {
        // Act
        final Stream<CameraClosingEvent> eventStream =
            camera.onCameraClosing(cameraId);
        final StreamQueue<CameraClosingEvent> streamQueue =
            StreamQueue<CameraClosingEvent>(eventStream);

        // Emit test events
        final CameraClosingEvent event = CameraClosingEvent(cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('camera_closing', event.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('camera_closing', event.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('camera_closing', event.toJson()), cameraId);

        // Assert
        expect(await streamQueue.next, event);
        expect(await streamQueue.next, event);
        expect(await streamQueue.next, event);

        // Clean up
        await streamQueue.cancel();
      });

      test('Should receive camera error events', () async {
        // Act
        final Stream<CameraErrorEvent> errorStream =
            camera.onCameraError(cameraId);
        final StreamQueue<CameraErrorEvent> streamQueue =
            StreamQueue<CameraErrorEvent>(errorStream);

        // Emit test events
        final CameraErrorEvent event =
            CameraErrorEvent(cameraId, 'Error Description');
        await camera.handleCameraMethodCall(
            MethodCall('error', event.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('error', event.toJson()), cameraId);
        await camera.handleCameraMethodCall(
            MethodCall('error', event.toJson()), cameraId);

        // Assert
        expect(await streamQueue.next, event);
        expect(await streamQueue.next, event);
        expect(await streamQueue.next, event);

        // Clean up
        await streamQueue.cancel();
      });

      test('Should receive device orientation change events', () async {
        // Act
        final Stream<DeviceOrientationChangedEvent> eventStream =
            camera.onDeviceOrientationChanged();
        final StreamQueue<DeviceOrientationChangedEvent> streamQueue =
            StreamQueue<DeviceOrientationChangedEvent>(eventStream);

        // Emit test events
        const DeviceOrientationChangedEvent event =
            DeviceOrientationChangedEvent(DeviceOrientation.portraitUp);
        await camera.handleDeviceMethodCall(
            MethodCall('orientation_changed', event.toJson()));
        await camera.handleDeviceMethodCall(
            MethodCall('orientation_changed', event.toJson()));
        await camera.handleDeviceMethodCall(
            MethodCall('orientation_changed', event.toJson()));

        // Assert
        expect(await streamQueue.next, event);
        expect(await streamQueue.next, event);
        expect(await streamQueue.next, event);

        // Clean up
        await streamQueue.cancel();
      });
    });

    group('Function Tests', () {
      late MethodChannelCamera camera;
      late int cameraId;

      setUp(() async {
        MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{
            'create': <String, dynamic>{'cameraId': 1},
            'initialize': null
          },
        );
        camera = MethodChannelCamera();
        cameraId = await camera.createCamera(
          const CameraDescription(
            name: 'Test',
            lensDirection: CameraLensDirection.back,
            sensorOrientation: 0,
          ),
          ResolutionPreset.high,
        );
        final Future<void> initializeFuture = camera.initializeCamera(cameraId);
        camera.cameraEventStreamController.add(
          CameraInitializedEvent(
            cameraId,
            1920,
            1080,
            ExposureMode.auto,
            true,
            FocusMode.auto,
            true,
          ),
        );
        await initializeFuture;
      });

      test('Should fetch CameraDescription instances for available cameras',
          () async {
        // Arrange
        final List<dynamic> returnData = <dynamic>[
          <String, dynamic>{
            'name': 'Test 1',
            'lensFacing': 'front',
            'sensorOrientation': 1
          },
          <String, dynamic>{
            'name': 'Test 2',
            'lensFacing': 'back',
            'sensorOrientation': 2
          }
        ];
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'availableCameras': returnData},
        );

        // Act
        final List<CameraDescription> cameras = await camera.availableCameras();

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('availableCameras', arguments: null),
        ]);
        expect(cameras.length, returnData.length);
        for (int i = 0; i < returnData.length; i++) {
          final Map<String, Object?> typedData =
              (returnData[i] as Map<dynamic, dynamic>).cast<String, Object?>();
          final CameraDescription cameraDescription = CameraDescription(
            name: typedData['name']! as String,
            lensDirection:
                parseCameraLensDirection(typedData['lensFacing']! as String),
            sensorOrientation: typedData['sensorOrientation']! as int,
          );
          expect(cameras[i], cameraDescription);
        }
      });

      test(
          'Should throw CameraException when availableCameras throws a PlatformException',
          () {
        // Arrange
        MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{
              'availableCameras': PlatformException(
                code: 'TESTING_ERROR_CODE',
                message: 'Mock error message used during testing.',
              )
            });

        // Act
        expect(
          camera.availableCameras,
          throwsA(
            isA<CameraException>()
                .having(
                    (CameraException e) => e.code, 'code', 'TESTING_ERROR_CODE')
                .having((CameraException e) => e.description, 'description',
                    'Mock error message used during testing.'),
          ),
        );
      });

      test('Should take a picture and return an XFile instance', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
            channelName: 'plugins.flutter.io/camera',
            methods: <String, dynamic>{'takePicture': '/test/path.jpg'});

        // Act
        final XFile file = await camera.takePicture(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('takePicture', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
        expect(file.path, '/test/path.jpg');
      });

      test('Should prepare for video recording', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'prepareForVideoRecording': null},
        );

        // Act
        await camera.prepareForVideoRecording();

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('prepareForVideoRecording', arguments: null),
        ]);
      });

      test('Should start recording a video', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'startVideoRecording': null},
        );

        // Act
        await camera.startVideoRecording(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('startVideoRecording', arguments: <String, Object?>{
            'cameraId': cameraId,
            'maxVideoDuration': null,
            'enableStream': false,
          }),
        ]);
      });

      test('Should pass maxVideoDuration when starting recording a video',
          () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'startVideoRecording': null},
        );

        // Act
        await camera.startVideoRecording(
          cameraId,
          maxVideoDuration: const Duration(seconds: 10),
        );

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('startVideoRecording', arguments: <String, Object?>{
            'cameraId': cameraId,
            'maxVideoDuration': 10000,
            'enableStream': false,
          }),
        ]);
      });

      test('Should stop a video recording and return the file', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'stopVideoRecording': '/test/path.mp4'},
        );

        // Act
        final XFile file = await camera.stopVideoRecording(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('stopVideoRecording', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
        expect(file.path, '/test/path.mp4');
      });

      test('Should pause a video recording', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'pauseVideoRecording': null},
        );

        // Act
        await camera.pauseVideoRecording(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('pauseVideoRecording', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
      });

      test('Should resume a video recording', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'resumeVideoRecording': null},
        );

        // Act
        await camera.resumeVideoRecording(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('resumeVideoRecording', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
      });

      test('Should set the flash mode', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setFlashMode': null},
        );

        // Act
        await camera.setFlashMode(cameraId, FlashMode.torch);
        await camera.setFlashMode(cameraId, FlashMode.always);
        await camera.setFlashMode(cameraId, FlashMode.auto);
        await camera.setFlashMode(cameraId, FlashMode.off);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('setFlashMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'torch'
          }),
          isMethodCall('setFlashMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'always'
          }),
          isMethodCall('setFlashMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'auto'
          }),
          isMethodCall('setFlashMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'off'
          }),
        ]);
      });

      test('Should set the exposure mode', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setExposureMode': null},
        );

        // Act
        await camera.setExposureMode(cameraId, ExposureMode.auto);
        await camera.setExposureMode(cameraId, ExposureMode.locked);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('setExposureMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'auto'
          }),
          isMethodCall('setExposureMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'locked'
          }),
        ]);
      });

      test('Should set the exposure point', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setExposurePoint': null},
        );

        // Act
        await camera.setExposurePoint(cameraId, const Point<double>(0.5, 0.5));
        await camera.setExposurePoint(cameraId, null);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('setExposurePoint', arguments: <String, Object?>{
            'cameraId': cameraId,
            'x': 0.5,
            'y': 0.5,
            'reset': false
          }),
          isMethodCall('setExposurePoint', arguments: <String, Object?>{
            'cameraId': cameraId,
            'x': null,
            'y': null,
            'reset': true
          }),
        ]);
      });

      test('Should get the min exposure offset', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'getMinExposureOffset': 2.0},
        );

        // Act
        final double minExposureOffset =
            await camera.getMinExposureOffset(cameraId);

        // Assert
        expect(minExposureOffset, 2.0);
        expect(channel.log, <Matcher>[
          isMethodCall('getMinExposureOffset', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
      });

      test('Should get the max exposure offset', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'getMaxExposureOffset': 2.0},
        );

        // Act
        final double maxExposureOffset =
            await camera.getMaxExposureOffset(cameraId);

        // Assert
        expect(maxExposureOffset, 2.0);
        expect(channel.log, <Matcher>[
          isMethodCall('getMaxExposureOffset', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
      });

      test('Should get the exposure offset step size', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'getExposureOffsetStepSize': 0.25},
        );

        // Act
        final double stepSize =
            await camera.getExposureOffsetStepSize(cameraId);

        // Assert
        expect(stepSize, 0.25);
        expect(channel.log, <Matcher>[
          isMethodCall('getExposureOffsetStepSize',
              arguments: <String, Object?>{
                'cameraId': cameraId,
              }),
        ]);
      });

      test('Should set the exposure offset', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setExposureOffset': 0.6},
        );

        // Act
        final double actualOffset =
            await camera.setExposureOffset(cameraId, 0.5);

        // Assert
        expect(actualOffset, 0.6);
        expect(channel.log, <Matcher>[
          isMethodCall('setExposureOffset', arguments: <String, Object?>{
            'cameraId': cameraId,
            'offset': 0.5,
          }),
        ]);
      });

      test('Should set the focus mode', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setFocusMode': null},
        );

        // Act
        await camera.setFocusMode(cameraId, FocusMode.auto);
        await camera.setFocusMode(cameraId, FocusMode.locked);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('setFocusMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'auto'
          }),
          isMethodCall('setFocusMode', arguments: <String, Object?>{
            'cameraId': cameraId,
            'mode': 'locked'
          }),
        ]);
      });

      test('Should set the exposure point', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setFocusPoint': null},
        );

        // Act
        await camera.setFocusPoint(cameraId, const Point<double>(0.5, 0.5));
        await camera.setFocusPoint(cameraId, null);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('setFocusPoint', arguments: <String, Object?>{
            'cameraId': cameraId,
            'x': 0.5,
            'y': 0.5,
            'reset': false
          }),
          isMethodCall('setFocusPoint', arguments: <String, Object?>{
            'cameraId': cameraId,
            'x': null,
            'y': null,
            'reset': true
          }),
        ]);
      });

      test('Should build a texture widget as preview widget', () async {
        // Act
        final Widget widget = camera.buildPreview(cameraId);

        // Act
        expect(widget is Texture, isTrue);
        expect((widget as Texture).textureId, cameraId);
      });

      test('Should throw MissingPluginException when handling unknown method',
          () {
        final MethodChannelCamera camera = MethodChannelCamera();

        expect(
            () => camera.handleCameraMethodCall(
                const MethodCall('unknown_method'), 1),
            throwsA(isA<MissingPluginException>()));
      });

      test('Should get the max zoom level', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'getMaxZoomLevel': 10.0},
        );

        // Act
        final double maxZoomLevel = await camera.getMaxZoomLevel(cameraId);

        // Assert
        expect(maxZoomLevel, 10.0);
        expect(channel.log, <Matcher>[
          isMethodCall('getMaxZoomLevel', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
      });

      test('Should get the min zoom level', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'getMinZoomLevel': 1.0},
        );

        // Act
        final double maxZoomLevel = await camera.getMinZoomLevel(cameraId);

        // Assert
        expect(maxZoomLevel, 1.0);
        expect(channel.log, <Matcher>[
          isMethodCall('getMinZoomLevel', arguments: <String, Object?>{
            'cameraId': cameraId,
          }),
        ]);
      });

      test('Should set the zoom level', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'setZoomLevel': null},
        );

        // Act
        await camera.setZoomLevel(cameraId, 2.0);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('setZoomLevel',
              arguments: <String, Object?>{'cameraId': cameraId, 'zoom': 2.0}),
        ]);
      });

      test('Should throw CameraException when illegal zoom level is supplied',
          () async {
        // Arrange
        MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{
            'setZoomLevel': PlatformException(
              code: 'ZOOM_ERROR',
              message: 'Illegal zoom error',
            )
          },
        );

        // Act & assert
        expect(
            () => camera.setZoomLevel(cameraId, -1.0),
            throwsA(isA<CameraException>()
                .having((CameraException e) => e.code, 'code', 'ZOOM_ERROR')
                .having((CameraException e) => e.description, 'description',
                    'Illegal zoom error')));
      });

      test('Should lock the capture orientation', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'lockCaptureOrientation': null},
        );

        // Act
        await camera.lockCaptureOrientation(
            cameraId, DeviceOrientation.portraitUp);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('lockCaptureOrientation', arguments: <String, Object?>{
            'cameraId': cameraId,
            'orientation': 'portraitUp'
          }),
        ]);
      });

      test('Should unlock the capture orientation', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'unlockCaptureOrientation': null},
        );

        // Act
        await camera.unlockCaptureOrientation(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('unlockCaptureOrientation',
              arguments: <String, Object?>{'cameraId': cameraId}),
        ]);
      });

      test('Should pause the camera preview', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'pausePreview': null},
        );

        // Act
        await camera.pausePreview(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('pausePreview',
              arguments: <String, Object?>{'cameraId': cameraId}),
        ]);
      });

      test('Should resume the camera preview', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{'resumePreview': null},
        );

        // Act
        await camera.resumePreview(cameraId);

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('resumePreview',
              arguments: <String, Object?>{'cameraId': cameraId}),
        ]);
      });

      test('Should start streaming', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{
            'startImageStream': null,
            'stopImageStream': null,
          },
        );

        // Act
        final StreamSubscription<CameraImageData> subscription = camera
            .onStreamedFrameAvailable(cameraId)
            .listen((CameraImageData imageData) {});

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('startImageStream', arguments: null),
        ]);

        subscription.cancel();
      });

      test('Should stop streaming', () async {
        // Arrange
        final MethodChannelMock channel = MethodChannelMock(
          channelName: 'plugins.flutter.io/camera',
          methods: <String, dynamic>{
            'startImageStream': null,
            'stopImageStream': null,
          },
        );

        // Act
        final StreamSubscription<CameraImageData> subscription = camera
            .onStreamedFrameAvailable(cameraId)
            .listen((CameraImageData imageData) {});
        subscription.cancel();

        // Assert
        expect(channel.log, <Matcher>[
          isMethodCall('startImageStream', arguments: null),
          isMethodCall('stopImageStream', arguments: null),
        ]);
      });
    });
  });
}
