// Copyright (c) 2015, 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 'package:http2/src/frames/frames.dart';
import 'package:http2/src/hpack/hpack.dart';
import 'package:http2/src/settings/settings.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import '../error_matchers.dart';

void main() {
  group('settings-handler', () {
    var pushSettings = [Setting(Setting.SETTINGS_ENABLE_PUSH, 0)];
    var invalidPushSettings = [Setting(Setting.SETTINGS_ENABLE_PUSH, 2)];
    var setMaxTable256 = [Setting(Setting.SETTINGS_HEADER_TABLE_SIZE, 256)];

    test('successful-setting', () async {
      var writer = FrameWriterMock();
      var sh = SettingsHandler(
        HPackEncoder(),
        writer,
        ActiveSettings(),
        ActiveSettings(),
      );

      // Start changing settings.
      var changed = sh.changeSettings(pushSettings);
      verify(writer.writeSettingsFrame(pushSettings)).called(1);
      verifyNoMoreInteractions(writer);

      // Check that settings haven't been applied.
      expect(sh.acknowledgedSettings.enablePush, true);

      // Simulate remote end to respond with an ACK.
      var header = FrameHeader(
        0,
        FrameType.SETTINGS,
        SettingsFrame.FLAG_ACK,
        0,
      );
      sh.handleSettingsFrame(SettingsFrame(header, []));

      await changed;

      // Check that settings have been applied.
      expect(sh.acknowledgedSettings.enablePush, false);
    });

    test('ack-remote-settings-change', () {
      var writer = FrameWriterMock();
      var sh = SettingsHandler(
        HPackEncoder(),
        writer,
        ActiveSettings(),
        ActiveSettings(),
      );

      // Check that settings haven't been applied.
      expect(sh.peerSettings.enablePush, true);

      // Simulate remote end by setting the push setting.
      var header = FrameHeader(6, FrameType.SETTINGS, 0, 0);
      sh.handleSettingsFrame(SettingsFrame(header, pushSettings));

      // Check that settings have been applied.
      expect(sh.peerSettings.enablePush, false);
      verify(writer.writeSettingsAckFrame()).called(1);
      verifyNoMoreInteractions(writer);
    });

    test('invalid-remote-ack', () {
      var writer = FrameWriterMock();
      var sh = SettingsHandler(
        HPackEncoder(),
        writer,
        ActiveSettings(),
        ActiveSettings(),
      );

      // Simulates ACK even though we haven't sent any settings.
      var header = FrameHeader(
        0,
        FrameType.SETTINGS,
        SettingsFrame.FLAG_ACK,
        0,
      );
      var settingsFrame = SettingsFrame(header, const []);

      expect(
        () => sh.handleSettingsFrame(settingsFrame),
        throwsA(isProtocolException),
      );
      verifyZeroInteractions(writer);
    });

    test('invalid-remote-settings-change', () {
      var writer = FrameWriterMock();
      var sh = SettingsHandler(
        HPackEncoder(),
        writer,
        ActiveSettings(),
        ActiveSettings(),
      );

      // Check that settings haven't been applied.
      expect(sh.peerSettings.enablePush, true);

      // Simulate remote end by setting the push setting.
      var header = FrameHeader(6, FrameType.SETTINGS, 0, 0);
      var settingsFrame = SettingsFrame(header, invalidPushSettings);
      expect(
        () => sh.handleSettingsFrame(settingsFrame),
        throwsA(isProtocolException),
      );
      verifyZeroInteractions(writer);
    });

    test('change-max-header-table-size', () {
      var writer = FrameWriterMock();
      var mock = HPackEncoderMock();
      var sh = SettingsHandler(
        mock,
        writer,
        ActiveSettings(),
        ActiveSettings(),
      );

      // Simulate remote end by setting the push setting.
      var header = FrameHeader(6, FrameType.SETTINGS, 0, 0);
      var settingsFrame = SettingsFrame(header, setMaxTable256);
      sh.handleSettingsFrame(settingsFrame);
      verify(mock.updateMaxSendingHeaderTableSize(256)).called(1);
      verify(writer.writeSettingsAckFrame()).called(1);
      verifyNoMoreInteractions(mock);
      verifyNoMoreInteractions(writer);
    });
  });
}

class FrameWriterMock extends Mock implements FrameWriter {}

class HPackEncoderMock extends Mock implements HPackEncoder {}
