// Copyright (c) 2013, 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 'package:test/test.dart';
import 'package:mime/mime.dart';

void _writeInChunks(
    List<int> data, int chunkSize, StreamController<List<int>> controller) {
  if (chunkSize == -1) chunkSize = data.length;

  for (var pos = 0; pos < data.length; pos += chunkSize) {
    var remaining = data.length - pos;
    var writeLength = min(chunkSize, remaining);
    controller.add(data.sublist(pos, pos + writeLength));
  }
  controller.close();
}

enum TestMode { IMMEDIATE_LISTEN, DELAY_LISTEN, PAUSE_RESUME }

void _runParseTest(String message, String boundary, TestMode mode,
    [List<Map> expectedHeaders, List expectedParts, bool expectError = false]) {
  Future testWrite(List<int> data, [int chunkSize = -1]) {
    var controller = StreamController<List<int>>(sync: true);

    var stream =
        controller.stream.transform(MimeMultipartTransformer(boundary));
    var i = 0;
    var completer = Completer();
    var futures = <Future>[];
    stream.listen((multipart) {
      var part = i++;
      if (expectedHeaders != null) {
        expect(multipart.headers, equals(expectedHeaders[part]));
      }
      switch (mode) {
        case TestMode.IMMEDIATE_LISTEN:
          futures.add(multipart
              .fold([], (buffer, data) => buffer..addAll(data)).then((data) {
            if (expectedParts[part] != null) {
              expect(data, equals(expectedParts[part].codeUnits));
            }
          }));
          break;

        case TestMode.DELAY_LISTEN:
          futures.add(Future(() {
            return multipart
                .fold([], (buffer, data) => buffer..addAll(data)).then((data) {
              if (expectedParts[part] != null) {
                expect(data, equals(expectedParts[part].codeUnits));
              }
            });
          }));
          break;

        case TestMode.PAUSE_RESUME:
          var completer = Completer();
          futures.add(completer.future);
          var buffer = [];
          var subscription;
          subscription = multipart.listen((data) {
            buffer.addAll(data);
            subscription.pause();
            Future(() => subscription.resume());
          }, onDone: () {
            if (expectedParts[part] != null) {
              expect(buffer, equals(expectedParts[part].codeUnits));
            }
            completer.complete();
          });
          break;
      }
    }, onError: (error) {
      if (!expectError) throw error;
    }, onDone: () {
      if (expectedParts != null) {
        expect(i, equals(expectedParts.length));
      }
      Future.wait(futures).then(completer.complete);
    });

    _writeInChunks(data, chunkSize, controller);

    return completer.future;
  }

  Future testFirstPartOnly(List<int> data, [int chunkSize = -1]) {
    var completer = Completer();
    var controller = StreamController<List<int>>(sync: true);

    var stream =
        controller.stream.transform(MimeMultipartTransformer(boundary));

    stream.first.then((multipart) {
      if (expectedHeaders != null) {
        expect(multipart.headers, equals(expectedHeaders[0]));
      }
      return (multipart.fold([], (b, d) => b..addAll(d)).then((data) {
        if (expectedParts != null && expectedParts[0] != null) {
          expect(data, equals(expectedParts[0].codeUnits));
        }
      }));
    }).then((_) {
      completer.complete();
    });

    _writeInChunks(data, chunkSize, controller);

    return completer.future;
  }

  Future testCompletePartAfterCancel(List<int> data, int parts,
      [int chunkSize = -1]) {
    var completer = Completer();
    var controller = StreamController<List<int>>(sync: true);
    var stream =
        controller.stream.transform(MimeMultipartTransformer(boundary));
    var subscription;
    var i = 0;
    var futures = <Future>[];
    subscription = stream.listen((multipart) {
      var partIndex = i;

      if (partIndex >= parts) {
        throw StateError('Expected no more parts, but got one.');
      }

      if (expectedHeaders != null) {
        expect(multipart.headers, equals(expectedHeaders[partIndex]));
      }
      futures.add((multipart.fold([], (b, d) => b..addAll(d)).then((data) {
        if (expectedParts != null && expectedParts[partIndex] != null) {
          expect(data, equals(expectedParts[partIndex].codeUnits));
        }
      })));

      if (partIndex == (parts - 1)) {
        subscription.cancel();
        Future.wait(futures).then(completer.complete);
      }
      i++;
    });

    _writeInChunks(data, chunkSize, controller);

    return completer.future;
  }

  // Test parsing the data three times delivering the data in
  // different chunks.
  var data = message.codeUnits;
  test('test', () {
    expect(
        Future.wait([
          testWrite(data),
          testWrite(data, 10),
          testWrite(data, 2),
          testWrite(data, 1),
        ]),
        completes);
  });

  if (expectedParts.isNotEmpty) {
    test('test-first-part-only', () {
      expect(
          Future.wait([
            testFirstPartOnly(data),
            testFirstPartOnly(data, 10),
            testFirstPartOnly(data, 2),
            testFirstPartOnly(data, 1),
          ]),
          completes);
    });

    test('test-n-parts-only', () {
      var numPartsExpected = expectedParts.length - 1;
      if (numPartsExpected == 0) numPartsExpected = 1;

      expect(
          Future.wait([
            testCompletePartAfterCancel(data, numPartsExpected),
            testCompletePartAfterCancel(data, numPartsExpected, 10),
            testCompletePartAfterCancel(data, numPartsExpected, 2),
            testCompletePartAfterCancel(data, numPartsExpected, 1),
          ]),
          completes);
    });
  }
}

void _testParse(String message, String boundary,
    [List<Map> expectedHeaders, List expectedParts, bool expectError = false]) {
  _runParseTest(message, boundary, TestMode.IMMEDIATE_LISTEN, expectedHeaders,
      expectedParts, expectError);
  _runParseTest(message, boundary, TestMode.DELAY_LISTEN, expectedHeaders,
      expectedParts, expectError);
  _runParseTest(message, boundary, TestMode.PAUSE_RESUME, expectedHeaders,
      expectedParts, expectError);
}

void _testParseValid() {
  // Empty message from Chrome form post.
  var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n';
  _testParse(message, '----WebKitFormBoundaryU3FBruSkJKG0Yor1', [], []);

  // Sample from Wikipedia.
  message = '''
This is a message with multiple parts in MIME format.\r
--frontier\r
Content-Type: text/plain\r
\r
This is the body of the message.\r
--frontier\r
Content-Type: application/octet-stream\r
Content-Transfer-Encoding: base64\r
\r
PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=\r
--frontier--\r\n''';
  var headers1 = <String, String>{'content-type': 'text/plain'};
  var headers2 = <String, String>{
    'content-type': 'application/octet-stream',
    'content-transfer-encoding': 'base64'
  };
  var body1 = 'This is the body of the message.';
  var body2 = '''
PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=''';
  _testParse(message, 'frontier', [headers1, headers2], [body1, body2]);

  // Sample from HTML 4.01 Specification.
  message = '''
\r\n--AaB03x\r
Content-Disposition: form-data; name=\"submit-name\"\r
\r
Larry\r
--AaB03x\r
Content-Disposition: form-data; name=\"files\"; filename=\"file1.txt\"\r
Content-Type: text/plain\r
\r
... contents of file1.txt ...\r
--AaB03x--\r\n''';
  headers1 = <String, String>{
    'content-disposition': 'form-data; name=\"submit-name\"'
  };
  headers2 = <String, String>{
    'content-type': 'text/plain',
    'content-disposition': 'form-data; name=\"files\"; filename=\"file1.txt\"'
  };
  body1 = 'Larry';
  body2 = '... contents of file1.txt ...';
  _testParse(message, 'AaB03x', [headers1, headers2], [body1, body2]);

  // Longer form from submitting the following from Chrome.
  //
  // <html>
  // <body>
  // <FORM action="http://127.0.0.1:1234/"
  //     enctype="multipart/form-data"
  //     method='post'>
  //  <P>
  //  Text: <INPUT type='text' name='text_input'>
  //  Password: <INPUT type='password' name='password_input'>
  //  Checkbox: <INPUT type='checkbox' name='checkbox_input'>
  //  Radio: <INPUT type='radio' name='radio_input'>
  //  Send <INPUT type='submit'>
  //  </P>
  // </FORM>
  // </body>
  // </html>

  message = '''
\r\n------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
Content-Disposition: form-data; name=\"text_input\"\r
\r
text\r
------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
Content-Disposition: form-data; name=\"password_input\"\r
\r
password\r
------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
Content-Disposition: form-data; name=\"checkbox_input\"\r
\r
on\r
------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
Content-Disposition: form-data; name=\"radio_input\"\r
\r
on\r
------WebKitFormBoundaryQ3cgYAmGRF8yOeYB--\r\n''';
  headers1 = <String, String>{
    'content-disposition': 'form-data; name=\"text_input\"'
  };
  headers2 = <String, String>{
    'content-disposition': 'form-data; name=\"password_input\"'
  };
  var headers3 = <String, String>{
    'content-disposition': 'form-data; name=\"checkbox_input\"'
  };
  var headers4 = <String, String>{
    'content-disposition': 'form-data; name=\"radio_input\"'
  };
  body1 = 'text';
  body2 = 'password';
  var body3 = 'on';
  var body4 = 'on';
  _testParse(message, '----WebKitFormBoundaryQ3cgYAmGRF8yOeYB',
      [headers1, headers2, headers3, headers4], [body1, body2, body3, body4]);

  // Same form from Firefox.
  message = '''
\r\n-----------------------------52284550912143824192005403738\r
Content-Disposition: form-data; name=\"text_input\"\r
\r
text\r
-----------------------------52284550912143824192005403738\r
Content-Disposition: form-data; name=\"password_input\"\r
\r
password\r
-----------------------------52284550912143824192005403738\r
Content-Disposition: form-data; name=\"checkbox_input\"\r
\r
on\r
-----------------------------52284550912143824192005403738\r
Content-Disposition: form-data; name=\"radio_input\"\r
\r
on\r
-----------------------------52284550912143824192005403738--\r\n''';
  _testParse(
      message,
      '---------------------------52284550912143824192005403738',
      [headers1, headers2, headers3, headers4],
      [body1, body2, body3, body4]);

  // And Internet Explorer
  message = '''
\r\n-----------------------------7dc8f38c60326\r
Content-Disposition: form-data; name=\"text_input\"\r
\r
text\r
-----------------------------7dc8f38c60326\r
Content-Disposition: form-data; name=\"password_input\"\r
\r
password\r
-----------------------------7dc8f38c60326\r
Content-Disposition: form-data; name=\"checkbox_input\"\r
\r
on\r
-----------------------------7dc8f38c60326\r
Content-Disposition: form-data; name=\"radio_input\"\r
\r
on\r
-----------------------------7dc8f38c60326--\r\n''';
  _testParse(message, '---------------------------7dc8f38c60326',
      [headers1, headers2, headers3, headers4], [body1, body2, body3, body4]);

  // Test boundary prefix inside prefix and content.
  message = '''
-\r
--\r
--b\r
--bo\r
--bou\r
--boun\r
--bound\r
--bounda\r
--boundar\r
--boundary\r
Content-Type: text/plain\r
\r
-\r
--\r
--b\r
--bo\r
--bou\r
--boun\r
--bound\r\r
--bounda\r\r\r
--boundar\r\r\r\r
--boundary\r
Content-Type: text/plain\r
\r
--boundar\r
--bounda\r
--bound\r
--boun\r
--bou\r
--bo\r
--b\r\r\r\r
--\r\r\r
-\r\r
--boundary--\r\n''';
  var headers = <String, String>{'content-type': 'text/plain'};
  body1 = '''
-\r
--\r
--b\r
--bo\r
--bou\r
--boun\r
--bound\r\r
--bounda\r\r\r
--boundar\r\r\r''';
  body2 = '''
--boundar\r
--bounda\r
--bound\r
--boun\r
--bou\r
--bo\r
--b\r\r\r\r
--\r\r\r
-\r''';
  _testParse(message, 'boundary', [headers, headers], [body1, body2]);

  // Without initial CRLF.
  message = '''
--xxx\r
\r
\r
Body 1\r
--xxx\r
\r
\r
Body2\r
--xxx--\r\n''';
  _testParse(message, 'xxx', null, ['\r\nBody 1', '\r\nBody2']);
}

void _testParseInvalid() {
  // Missing end boundary.
  var message = '''
\r
--xxx\r
\r
\r
Body 1\r
--xxx\r
\r
\r
Body2\r
--xxx\r\n''';
  _testParse(message, 'xxx', null, [null, null], true);
}

void main() {
  _testParseValid();
  _testParseInvalid();
}
