// Copyright (c) 2014, 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:convert';

import 'char_code.dart' as char_code;
import 'mime_shared.dart';

/// Bytes for '()<>@,;:\\"/[]?={} \t'.
const _separators = {
  40, 41, 60, 62, 64, 44, 59, 58, 92, 34, 47, 91, 93, 63, 61, 123, 125, 32, 9 //
};

bool _isTokenChar(int byte) =>
    byte > 31 && byte < 128 && !_separators.contains(byte);

int _toLowerCase(int byte) {
  const delta = char_code.lowerA - char_code.upperA;
  return (char_code.upperA <= byte && byte <= char_code.upperZ)
      ? byte + delta
      : byte;
}

void _expectByteValue(int val1, int val2) {
  if (val1 != val2) {
    throw const MimeMultipartException('Failed to parse multipart mime 1');
  }
}

void _expectWhitespace(int byte) {
  if (byte != char_code.sp && byte != char_code.ht) {
    throw const MimeMultipartException('Failed to parse multipart mime 2');
  }
}

class _MimeMultipart extends MimeMultipart {
  @override
  final Map<String, String> headers;
  final Stream<List<int>> _stream;

  _MimeMultipart(this.headers, this._stream);

  @override
  StreamSubscription<List<int>> listen(
    void Function(List<int> data)? onData, {
    void Function()? onDone,
    Function? onError,
    bool? cancelOnError,
  }) =>
      _stream.listen(
        onData,
        onDone: onDone,
        onError: onError,
        cancelOnError: cancelOnError,
      );
}

class BoundMultipartStream {
  static const int _startCode = 0;
  static const int _boundaryEndingCode = 1;
  static const int _boundaryEndCode = 2;
  static const int _headerStartCode = 3;
  static const int _headerFieldCode = 4;
  static const int _headerValueStartCode = 5;
  static const int _headerValueCode = 6;
  static const int _headerValueFoldingOrEndingCode = 7;
  static const int _headerValueFoldOrEndCode = 8;
  static const int _headerEndingCode = 9;
  static const int _contentCode = 10;
  static const int _lastBoundaryDash2Code = 11;
  static const int _lastBoundaryEndingCode = 12;
  static const int _lastBoundaryEndCode = 13;
  static const int _doneCode = 14;
  static const int _failCode = 15;

  final List<int> _boundary;
  final List<int> _headerField = [];
  final List<int> _headerValue = [];

  // The following states belong to `_controller`, state changes will not be
  // immediately acted upon but rather only after the current
  // `_multipartController` is done.
  static const int _controllerStateIdle = 0;
  static const int _controllerStateActive = 1;
  static const int _controllerStatePaused = 2;
  static const int _controllerStateCanceled = 3;

  int _controllerState = _controllerStateIdle;

  final _controller = StreamController<MimeMultipart>(sync: true);

  Stream<MimeMultipart> get stream => _controller.stream;

  late StreamSubscription<void> _subscription;

  StreamController<List<int>>? _multipartController;
  Map<String, String>? _headers;

  int _state = _startCode;
  int _boundaryIndex = 2;

  /// Current index into [_buffer].
  ///
  /// If index is negative then it is the index into the artificial prefix of
  /// the boundary string.
  int _index = 0;
  List<int> _buffer = _placeholderBuffer;

  BoundMultipartStream(this._boundary, Stream<List<int>> stream) {
    _controller
      ..onPause = _pauseStream
      ..onResume = _resumeStream
      ..onCancel = () {
        _controllerState = _controllerStateCanceled;
        _tryPropagateControllerState();
      }
      ..onListen = () {
        _controllerState = _controllerStateActive;
        _subscription = stream.listen((data) {
          assert(_buffer == _placeholderBuffer);
          _subscription.pause();
          _buffer = data;
          _index = 0;
          _parse();
        }, onDone: () {
          if (_state != _doneCode) {
            _controller
                .addError(const MimeMultipartException('Bad multipart ending'));
          }
          _controller.close();
        }, onError: _controller.addError);
      };
  }

  void _resumeStream() {
    assert(_controllerState == _controllerStatePaused);
    _controllerState = _controllerStateActive;
    _tryPropagateControllerState();
  }

  void _pauseStream() {
    _controllerState = _controllerStatePaused;
    _tryPropagateControllerState();
  }

  void _tryPropagateControllerState() {
    if (_multipartController == null) {
      switch (_controllerState) {
        case _controllerStateActive:
          if (_subscription.isPaused) _subscription.resume();
        case _controllerStatePaused:
          if (!_subscription.isPaused) _subscription.pause();
        case _controllerStateCanceled:
          _subscription.cancel();
        default:
          throw StateError('This code should never be reached.');
      }
    }
  }

  void _parse() {
    // Number of boundary bytes to artificially place before the supplied data.
    // The data to parse might be 'artificially' prefixed with a
    // partial match of the boundary.
    final boundaryPrefix = _boundaryIndex;
    // Position where content starts. Will be null if no known content
    // start exists. Will be negative of the content starts in the
    // boundary prefix. Will be zero or position if the content starts
    // in the current buffer.
    var contentStartIndex =
        _state == _contentCode && _boundaryIndex == 0 ? 0 : null;

    // Function to report content data for the current part. The data
    // reported is from the current content start index up til the
    // current index. As the data can be artificially prefixed with a
    // prefix of the boundary both the content start index and index
    // can be negative.
    void reportData() {
      if (contentStartIndex! < 0) {
        final contentLength = boundaryPrefix + _index - _boundaryIndex;
        if (contentLength <= boundaryPrefix) {
          _multipartController!.add(_boundary.sublist(0, contentLength));
        } else {
          _multipartController!.add(_boundary.sublist(0, boundaryPrefix));
          _multipartController!
              .add(_buffer.sublist(0, contentLength - boundaryPrefix));
        }
      } else {
        final contentEndIndex = _index - _boundaryIndex;
        _multipartController!
            .add(_buffer.sublist(contentStartIndex, contentEndIndex));
      }
    }

    while (
        _index < _buffer.length && _state != _failCode && _state != _doneCode) {
      final byte =
          _index < 0 ? _boundary[boundaryPrefix + _index] : _buffer[_index];
      switch (_state) {
        case _startCode:
          if (byte == _boundary[_boundaryIndex]) {
            _boundaryIndex++;
            if (_boundaryIndex == _boundary.length) {
              _state = _boundaryEndingCode;
              _boundaryIndex = 0;
            }
          } else {
            // Restart matching of the boundary.
            _index = _index - _boundaryIndex;
            _boundaryIndex = 0;
          }

        case _boundaryEndingCode:
          if (byte == char_code.cr) {
            _state = _boundaryEndCode;
          } else if (byte == char_code.dash) {
            _state = _lastBoundaryDash2Code;
          } else {
            _expectWhitespace(byte);
          }

        case _boundaryEndCode:
          _expectByteValue(byte, char_code.lf);
          _multipartController?.close();
          if (_multipartController != null) {
            _multipartController = null;
            _tryPropagateControllerState();
          }
          _state = _headerStartCode;

        case _headerStartCode:
          _headers = <String, String>{};
          if (byte == char_code.cr) {
            _state = _headerEndingCode;
          } else {
            // Start of new header field.
            _headerField.add(_toLowerCase(byte));
            _state = _headerFieldCode;
          }

        case _headerFieldCode:
          if (byte == char_code.colon) {
            _state = _headerValueStartCode;
          } else {
            if (!_isTokenChar(byte)) {
              throw const MimeMultipartException('Invalid header field name');
            }
            _headerField.add(_toLowerCase(byte));
          }

        case _headerValueStartCode:
          if (byte == char_code.cr) {
            _state = _headerValueFoldingOrEndingCode;
          } else if (byte != char_code.sp && byte != char_code.ht) {
            // Start of new header value.
            _headerValue.add(byte);
            _state = _headerValueCode;
          }

        case _headerValueCode:
          if (byte == char_code.cr) {
            _state = _headerValueFoldingOrEndingCode;
          } else {
            _headerValue.add(byte);
          }

        case _headerValueFoldingOrEndingCode:
          _expectByteValue(byte, char_code.lf);
          _state = _headerValueFoldOrEndCode;

        case _headerValueFoldOrEndCode:
          if (byte == char_code.sp || byte == char_code.ht) {
            _state = _headerValueStartCode;
          } else {
            final headerField = utf8.decode(_headerField);
            final headerValue = utf8.decode(_headerValue);
            _headers![headerField.toLowerCase()] = headerValue;
            _headerField.clear();
            _headerValue.clear();
            if (byte == char_code.cr) {
              _state = _headerEndingCode;
            } else {
              // Start of new header field.
              _headerField.add(_toLowerCase(byte));
              _state = _headerFieldCode;
            }
          }

        case _headerEndingCode:
          _expectByteValue(byte, char_code.lf);
          _multipartController = StreamController(
              sync: true,
              onListen: () {
                if (_subscription.isPaused) _subscription.resume();
              },
              onPause: _subscription.pause,
              onResume: _subscription.resume);
          _controller
              .add(_MimeMultipart(_headers!, _multipartController!.stream));
          _headers = null;
          _state = _contentCode;
          contentStartIndex = _index + 1;

        case _contentCode:
          if (byte == _boundary[_boundaryIndex]) {
            _boundaryIndex++;
            if (_boundaryIndex == _boundary.length) {
              if (contentStartIndex != null) {
                _index++;
                reportData();
                _index--;
              }
              _multipartController!.close();
              _multipartController = null;
              _tryPropagateControllerState();
              _boundaryIndex = 0;
              _state = _boundaryEndingCode;
            }
          } else {
            // Restart matching of the boundary.
            _index = _index - _boundaryIndex;
            contentStartIndex ??= _index;
            _boundaryIndex = 0;
          }

        case _lastBoundaryDash2Code:
          _expectByteValue(byte, char_code.dash);
          _state = _lastBoundaryEndingCode;

        case _lastBoundaryEndingCode:
          if (byte == char_code.cr) {
            _state = _lastBoundaryEndCode;
          } else {
            _expectWhitespace(byte);
          }

        case _lastBoundaryEndCode:
          _expectByteValue(byte, char_code.lf);
          _multipartController?.close();
          if (_multipartController != null) {
            _multipartController = null;
            _tryPropagateControllerState();
          }
          _state = _doneCode;

        default:
          // Should be unreachable.
          assert(false);
          break;
      }

      // Move to the next byte.
      _index++;
    }

    // Report any known content.
    if (_state == _contentCode && contentStartIndex != null) {
      reportData();
    }

    // Resume if at end.
    if (_index == _buffer.length) {
      _buffer = _placeholderBuffer;
      _index = 0;
      _subscription.resume();
    }
  }
}

// Used as a placeholder instead of having a nullable buffer.
const _placeholderBuffer = <int>[];
