// Copyright (c) 2012, 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.

library XHRTest;

import 'dart:async';
import 'dart:convert';
import 'dart:html';
import 'dart:typed_data';

import 'package:expect/legacy/async_minitest.dart'; // ignore: deprecated_member_use
import 'package:expect/async_helper.dart';

// Cache blocker is a workaround for:
// https://code.google.com/p/dart/issues/detail?id=11834
var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
var url =
    '/root_dart/tests/lib/html/xhr_cross_origin_data.txt?'
    'cacheBlock=$cacheBlocker';

void validate200Response(xhr) {
  expect(xhr.status, 200);
  var data = json.decode(xhr.responseText);
  expect(data.containsKey('feed'), isTrue);
  expect(data['feed'].containsKey('entry'), isTrue);
  expect(data, isMap);
}

void validate404(xhr) {
  expect(xhr.status, 404);
  // We cannot say much about xhr.responseText, most HTTP servers will
  // include an HTML page explaining the error to a human.
  String responseText = xhr.responseText;
  expect(responseText, isNotNull);
}

Future testXhrNoFile() async {
  HttpRequest xhr = new HttpRequest();
  xhr.open("GET", "NonExistingFile", async: true);
  var completer = new Completer<void>();
  xhr.onReadyStateChange.listen((event) {
    if (!completer.isCompleted && xhr.readyState == HttpRequest.DONE) {
      completer.complete();
      validate404(xhr);
    }
  });
  xhr.send();
  await completer;
}

Future testXhrFile() async {
  var loadEndCalled = false;

  var xhr = new HttpRequest();
  xhr.open('GET', url, async: true);
  var completer = new Completer<void>();
  xhr.onReadyStateChange.listen((e) {
    if (!completer.isCompleted && xhr.readyState == HttpRequest.DONE) {
      completer.complete();
      validate200Response(xhr);

      Timer.run(
        expectAsync(() {
          expect(loadEndCalled, HttpRequest.supportsLoadEndEvent);
        }),
      );
    }
  });

  xhr.onLoadEnd.listen((ProgressEvent e) {
    loadEndCalled = true;
  });
  xhr.send();
  await completer;
}

Future testRequestNoFile() async {
  try {
    await HttpRequest.request('NonExistingFile');
    fail('Request should not have succeeded.');
  } on ProgressEvent catch (error) {
    HttpRequest xhr = error.target as HttpRequest;
    expect(xhr.readyState, HttpRequest.DONE);
    validate404(xhr);
  }
}

Future testRequestFile() async {
  var xhr = await HttpRequest.request(url);
  expect(xhr.readyState, HttpRequest.DONE);
  validate200Response(xhr);
}

Future testRequestOnProgress() async {
  var progressCalled = false;
  var xhr = await HttpRequest.request(
    url,
    onProgress: (_) {
      progressCalled = true;
    },
  );
  expect(xhr.readyState, HttpRequest.DONE);
  expect(progressCalled, HttpRequest.supportsProgressEvent);
  validate200Response(xhr);
}

Future testRequestWithCredentialsNoFile() async {
  try {
    await HttpRequest.request('NonExistingFile', withCredentials: true);
    fail('Request should not have succeeded.');
  } on ProgressEvent catch (error) {
    HttpRequest xhr = error.target as HttpRequest;
    expect(xhr.readyState, HttpRequest.DONE);
    validate404(xhr);
  }
}

Future testRequestWithCredentialsFile() async {
  try {
    HttpRequest xhr = await HttpRequest.request(url, withCredentials: true);
    expect(xhr.readyState, HttpRequest.DONE);
    validate200Response(xhr);
  } catch (_) {
    fail('Request should succeed.');
  }
}

Future testGetStringFile() => HttpRequest.getString(url);

Future testGetStringNoFile() async {
  try {
    await HttpRequest.getString('NonExistingFile');
    fail('Succeeded for non-existing file.');
  } on ProgressEvent catch (error) {
    HttpRequest xhr = error.target as HttpRequest;
    expect(xhr.readyState, HttpRequest.DONE);
    validate404(xhr);
  }
}

Future testRequestResponseTypeArrayBuffer() async {
  if (Platform.supportsTypedData) {
    var xhr = await HttpRequest.request(
      url,
      responseType: 'arraybuffer',
      requestHeaders: {'Content-Type': 'text/xml'},
    );
    expect(xhr.status, 200);
    var byteBuffer = xhr.response;
    expect(byteBuffer, isInstanceOf<ByteBuffer>());
    expect(byteBuffer, isNotNull);
  }
}

Future testOverrideMimeType() async {
  bool gotError = false;
  try {
    await HttpRequest.request(url, mimeType: 'application/binary');
  } catch (_) {
    gotError = true;
  }
  expect(gotError, !HttpRequest.supportsOverrideMimeType);
}

Future testXhrUpload() async {
  if (Platform.supportsTypedData) {
    var xhr = new HttpRequest();
    var progressCalled = false;
    xhr.upload.onProgress.listen((e) {
      progressCalled = true;
    });

    xhr.open(
      'POST',
      '${window.location.protocol}//${window.location.host}/echo',
    );

    // 10MB of payload data w/ a bit of data to make sure it
    // doesn't get compressed to nil.
    var data = new Uint8List(1 * 1024 * 1024);
    for (var i = 0; i < data.length; ++i) {
      data[i] = i & 0xFF;
    }
    xhr.send(new Uint8List.view(data.buffer));

    await xhr.onLoad.first;
    expect(progressCalled, isTrue, reason: 'onProgress should be fired');
  }
}

Future testXhrPostFormData() async {
  var data = {'name': 'John', 'time': '2 pm'};

  var parts = [];
  for (var key in data.keys) {
    parts.add(
      '${Uri.encodeQueryComponent(key)}='
      '${Uri.encodeQueryComponent(data[key]!)}',
    );
  }
  var encodedData = parts.join('&');

  var xhr = await HttpRequest.postFormData(
    '${window.location.protocol}//${window.location.host}/echo',
    data,
  );
  expect(xhr.responseText, encodedData);
}

Future testRequestResponseTypeBlob() async {
  if (Platform.supportsTypedData) {
    var xhr = await HttpRequest.request(url, responseType: 'blob');
    expect(xhr.status, 200);
    var blob = xhr.response;
    expect(blob is Blob, isTrue);
    expect(blob, isNotNull);
  }
}

Future testResponseTypeJson() async {
  var url = '${window.location.protocol}//${window.location.host}/echo';
  var data = {'key': 'value', 'a': 'b', 'one': 2};

  var xhr = await HttpRequest.request(
    url,
    method: 'POST',
    sendData: json.encode(data),
    responseType: 'json',
  );
  expect(xhr.status, 200);
  var jsonResponse = xhr.response;
  expect(jsonResponse, data);
}

Future testResponseHeaders() async {
  var xhr = await HttpRequest.request(url);
  var contentTypeHeader = xhr.responseHeaders['content-type'];
  expect(contentTypeHeader, isNotNull);
  // Should be like: 'text/plain; charset=utf-8'
  expect(contentTypeHeader!.contains('text/plain'), isTrue);
  expect(contentTypeHeader.contains('charset=utf-8'), isTrue);
}

main() {
  test('supportsProgressEvent', () {
    expect(HttpRequest.supportsProgressEvent, isTrue);
  });

  test('supportsOnLoadEnd', () {
    expect(HttpRequest.supportsLoadEndEvent, isTrue);
  });

  test('supportsOverrideMimeType', () {
    expect(HttpRequest.supportsOverrideMimeType, isTrue);
  });

  asyncTest(() async {
    await testXhrNoFile();
    await testXhrFile();
    await testRequestNoFile();
    await testRequestFile();
    await testRequestOnProgress();
    await testRequestWithCredentialsNoFile();
    await testRequestWithCredentialsFile();
    await testGetStringFile();
    await testGetStringNoFile();
    await testRequestResponseTypeArrayBuffer();
    await testOverrideMimeType();
    await testXhrUpload();
    await testXhrPostFormData();

    await testRequestResponseTypeBlob();

    await testResponseTypeJson();

    await testResponseHeaders();
  });
}
