// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

@TestOn('chrome') // Uses web-only Flutter SDK

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

import 'package:cross_file/cross_file.dart';
import 'package:js/js_util.dart' as js_util;
import 'package:test/test.dart';

const String expectedStringContents = 'Hello, world! I ❤ ñ! 空手';
final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents));
final html.File textFile = html.File(<Object>[bytes], 'hello.txt');
final String textFileUrl = html.Url.createObjectUrl(textFile);

void main() {
  group('Create with an objectUrl', () {
    final XFile file = XFile(textFileUrl);

    test('Can be read as a string', () async {
      expect(await file.readAsString(), equals(expectedStringContents));
    });

    test('Can be read as bytes', () async {
      expect(await file.readAsBytes(), equals(bytes));
    });

    test('Can be read as a stream', () async {
      expect(await file.openRead().first, equals(bytes));
    });

    test('Stream can be sliced', () async {
      expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5)));
    });
  });

  group('Create from data', () {
    final XFile file = XFile.fromData(bytes);

    test('Can be read as a string', () async {
      expect(await file.readAsString(), equals(expectedStringContents));
    });

    test('Can be read as bytes', () async {
      expect(await file.readAsBytes(), equals(bytes));
    });

    test('Can be read as a stream', () async {
      expect(await file.openRead().first, equals(bytes));
    });

    test('Stream can be sliced', () async {
      expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5)));
    });
  });

  group('Blob backend', () {
    final XFile file = XFile(textFileUrl);

    test('Stores data as a Blob', () async {
      // Read the blob from its path 'natively'
      final Object response = await html.window.fetch(file.path) as Object;
      // Call '.arrayBuffer()' on the fetch response object to look at its bytes.
      final ByteBuffer data = await js_util.promiseToFuture(
        js_util.callMethod(response, 'arrayBuffer', <Object?>[]),
      );
      expect(data.asUint8List(), equals(bytes));
    });

    test('Data may be purged from the blob!', () async {
      html.Url.revokeObjectUrl(file.path);

      expect(() async {
        await file.readAsBytes();
      }, throwsException);
    });
  });

  group('saveTo(..)', () {
    const String crossFileDomElementId = '__x_file_dom_element';

    group('CrossFile saveTo(..)', () {
      test('creates a DOM container', () async {
        final XFile file = XFile.fromData(bytes);

        await file.saveTo('');

        final html.Element? container =
            html.querySelector('#$crossFileDomElementId');

        expect(container, isNotNull);
      });

      test('create anchor element', () async {
        final XFile file = XFile.fromData(bytes, name: textFile.name);

        await file.saveTo('path');

        final html.Element container =
            html.querySelector('#$crossFileDomElementId')!;
        final html.AnchorElement element = container.children
                .firstWhere((html.Element element) => element.tagName == 'A')
            as html.AnchorElement;

        // if element is not found, the `firstWhere` call will throw StateError.
        expect(element.href, file.path);
        expect(element.download, file.name);
      });

      test('anchor element is clicked', () async {
        final html.AnchorElement mockAnchor = html.AnchorElement();

        final CrossFileTestOverrides overrides = CrossFileTestOverrides(
          createAnchorElement: (_, __) => mockAnchor,
        );

        final XFile file =
            XFile.fromData(bytes, name: textFile.name, overrides: overrides);

        bool clicked = false;
        mockAnchor.onClick.listen((html.MouseEvent event) => clicked = true);

        await file.saveTo('path');

        expect(clicked, true);
      });
    });
  });
}
