// Copyright 2014 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 'package:flutter_driver/src/common/error.dart';
import 'package:flutter_driver/src/common/health.dart';
import 'package:flutter_driver/src/driver/web_driver.dart';
import 'package:webdriver/src/common/log.dart';

import '../../common.dart';

void main() {
  group('WebDriver', () {
    late FakeFlutterWebConnection fakeConnection;
    late WebFlutterDriver driver;

    setUp(() {
      fakeConnection = FakeFlutterWebConnection();
      driver = WebFlutterDriver.connectedTo(fakeConnection);
    });

    test('sendCommand succeeds', () async {
      fakeConnection.fakeResponse = '''
{
  "isError": false,
  "response": {
    "test": "hello"
  }
}
''';

      final Map<String, Object?> response = await driver.sendCommand(const GetHealth());
      expect(response['test'], 'hello');
    });

    test('sendCommand fails on communication error', () async {
      fakeConnection.communicationError = Error();
      expect(
        () => driver.sendCommand(const GetHealth()),
        _throwsDriverErrorWithMessage(
          'FlutterDriver command GetHealth failed due to a remote error.\n'
          'Command sent: {"command":"get_health"}'
        ),
      );
    });

    test('sendCommand fails on null', () async {
      fakeConnection.fakeResponse = null;
      expect(
        () => driver.sendCommand(const GetHealth()),
        _throwsDriverErrorWithDataString('Null', 'null'),
      );
    });

    test('sendCommand fails when response data is not a string', () async {
      fakeConnection.fakeResponse = 1234;
      expect(
        () => driver.sendCommand(const GetHealth()),
        _throwsDriverErrorWithDataString('int', '1234'),
      );
    });

    test('sendCommand fails when isError is true', () async {
      fakeConnection.fakeResponse = '''
{
  "isError": true,
  "response": "test error message"
}
''';
      expect(
        () => driver.sendCommand(const GetHealth()),
        _throwsDriverErrorWithMessage(
          'Error in Flutter application: test error message'
        ),
      );
    });

    test('sendCommand fails when isError is not bool', () async {
      fakeConnection.fakeResponse = '{ "isError": 5 }';
      expect(
        () => driver.sendCommand(const GetHealth()),
        _throwsDriverErrorWithDataString('String', '{ "isError": 5 }'),
      );
    });

    test('sendCommand fails when "response" field is not a JSON map', () async {
      fakeConnection.fakeResponse = '{ "response": 5 }';
      expect(
        () => driver.sendCommand(const GetHealth()),
        _throwsDriverErrorWithDataString('String', '{ "response": 5 }'),
      );
    });
  });
}

Matcher _throwsDriverErrorWithMessage(String expectedMessage) {
  return throwsA(allOf(
    isA<DriverError>(),
    predicate<DriverError>((DriverError error) {
      final String actualMessage = error.message;
      return actualMessage == expectedMessage;
    }, 'contains message: $expectedMessage'),
  ));
}

Matcher _throwsDriverErrorWithDataString(String dataType, String dataString) {
  return _throwsDriverErrorWithMessage(
    'Received malformed response from the FlutterDriver extension.\n'
    'Expected a JSON map containing a "response" field and, optionally, an '
    '"isError" field, but got $dataType: $dataString'
  );
}

class FakeFlutterWebConnection implements FlutterWebConnection {
  @override
  bool supportsTimelineAction = false;

  @override
  Future<void> close() async {}

  @override
  Stream<LogEntry> get logs => throw UnimplementedError();

  @override
  Future<List<int>> screenshot() {
    throw UnimplementedError();
  }

  Object? fakeResponse;
  Error? communicationError;

  @override
  Future<Object?> sendCommand(String script, Duration? duration) async {
    if (communicationError != null) {
      throw communicationError!;
    }
    return fakeResponse;
  }
}
