// 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 'dart:async';
import 'dart:math';

import 'byte_utils.dart';

/// This is a set of bytes with which a client connection begins in the normal
/// case. It can be used on a server to distinguish HTTP/1.1 and HTTP/2 clients.
const List<int> CONNECTION_PREFACE = [
  0x50,
  0x52,
  0x49,
  0x20,
  0x2a,
  0x20,
  0x48,
  0x54,
  0x54,
  0x50,
  0x2f,
  0x32,
  0x2e,
  0x30,
  0x0d,
  0x0a,
  0x0d,
  0x0a,
  0x53,
  0x4d,
  0x0d,
  0x0a,
  0x0d,
  0x0a
];

/// Reads the connection preface from [incoming].
///
/// The returned `Stream` will be a duplicate of `incoming` without the
/// connection preface. If an error occurs while reading the connection
/// preface, the returned stream will have only an error.
Stream<List<int>> readConnectionPreface(Stream<List<int>> incoming) {
  final result = StreamController<List<int>>();
  late StreamSubscription subscription;
  var connectionPrefaceRead = false;
  var prefaceBuffer = <int>[];
  var terminated = false;

  void terminate(Object error) {
    if (!terminated) {
      result.addError(error);
      result.close();
      subscription.cancel();
    }
    terminated = true;
  }

  bool compareConnectionPreface(List<int> data) {
    for (var i = 0; i < CONNECTION_PREFACE.length; i++) {
      if (data[i] != CONNECTION_PREFACE[i]) {
        terminate('Connection preface does not match.');
        return false;
      }
    }
    connectionPrefaceRead = true;
    return true;
  }

  void onData(List<int> data) {
    if (connectionPrefaceRead) {
      // Forward data after reading preface.
      result.add(data);
    } else {
      if (prefaceBuffer.isEmpty && data.length > CONNECTION_PREFACE.length) {
        if (!compareConnectionPreface(data)) return;
        data = data.sublist(CONNECTION_PREFACE.length);
      } else if (prefaceBuffer.length < CONNECTION_PREFACE.length) {
        var remaining = CONNECTION_PREFACE.length - prefaceBuffer.length;

        var end = min(data.length, remaining);
        var part1 = viewOrSublist(data, 0, end);
        var part2 = viewOrSublist(data, end, data.length - end);
        prefaceBuffer.addAll(part1);

        if (prefaceBuffer.length == CONNECTION_PREFACE.length) {
          if (!compareConnectionPreface(prefaceBuffer)) return;
        }
        data = part2;
      }
      if (data.isNotEmpty) {
        result.add(data);
      }
    }
  }

  result.onListen = () {
    subscription =
        incoming.listen(onData, onError: result.addError, onDone: () {
      if (!connectionPrefaceRead) {
        terminate('EOS before connection preface could be read.');
      } else {
        result.close();
      }
    });
    result
      ..onPause = subscription.pause
      ..onResume = subscription.resume
      ..onCancel = subscription.cancel;
  };

  return result.stream;
}
